diff --git a/class/Image/primitive.c b/class/Image/primitive.c index 29e1b2934..b657fe6af 100644 --- a/class/Image/primitive.c +++ b/class/Image/primitive.c @@ -326,9 +326,8 @@ prepare_line_context( Handle self, unsigned char * lp, ImgPaintContext * ctx) ctx->linePattern = lp; } - -static Bool -primitive( Handle self, Bool fill, char * method, ...) +Bool +Image_draw_primitive( Handle self, Bool fill, char * method, ...) { Bool r; SV * ret; @@ -356,7 +355,7 @@ Image_arc( Handle self, double x, double y, double dX, double dY, double startAn { if ( opt_InPaint) return inherited arc(self, x, y, dX, dY, startAngle, endAngle); while ( startAngle > endAngle ) endAngle += 360.0; - return primitive( self, 0, "snnnnnn", "arc", x, y, dX, dY, startAngle, endAngle); + return Image_draw_primitive( self, 0, "snnnnnn", "arc", x, y, dX, dY, startAngle, endAngle); } Bool @@ -371,7 +370,7 @@ Image_bar( Handle self, double x1, double y1, double x2, double y2) if (opt_InPaint) return inherited bar( self, x1, y1, x2, y2); else if ( var-> antialias ) { - ok = primitive( self, 1, "snnnn", "rectangle", x1, y1, x2, y2); + ok = Image_draw_primitive( self, 1, "snnnn", "rectangle", x1, y1, x2, y2); my-> update_change(self); return ok; } @@ -390,7 +389,7 @@ Image_bar( Handle self, double x1, double y1, double x2, double y2) points = prima_array_tie( sv, sizeof(double), "d"); COPY_MATRIX(VAR_MATRIX, save); COPY_MATRIX(identity, VAR_MATRIX); - ok = primitive( self, 1, "sS", "line", points ); + ok = Image_draw_primitive( self, 1, "sS", "line", points ); COPY_MATRIX(save, VAR_MATRIX); sv_free(points); my-> update_change(self); @@ -425,7 +424,7 @@ Image_bars( Handle self, SV * rects) if (( p = prima_read_array( rects, "Image::bars", 'd', 4, 0, -1, &count, &do_free)) == NULL) return false; for ( i = 0, r = p; i < count; i++, r++) { - ok = primitive( self, 1, "snnnn", "rectangle", + ok = Image_draw_primitive( self, 1, "snnnn", "rectangle", r->left, r->bottom, r->right - r->left, @@ -462,7 +461,7 @@ Image_bars( Handle self, SV * rects) points = prima_array_tie( sv, sizeof(double), "d"); } memcpy( storage, npoly, sizeof(npoly)); - ok &= primitive( self, 1, "sS", "line", points ); + ok &= Image_draw_primitive( self, 1, "sS", "line", points ); continue; } @@ -488,7 +487,7 @@ Bool Image_chord( Handle self, double x, double y, double dX, double dY, double startAngle, double endAngle) { if ( opt_InPaint) return inherited chord(self, x, y, dX, dY, startAngle, endAngle); - return primitive( self, 0, "snnnnnn", "chord", x, y, dX, dY, startAngle, endAngle); + return Image_draw_primitive( self, 0, "snnnnnn", "chord", x, y, dX, dY, startAngle, endAngle); } Bool @@ -507,7 +506,7 @@ Image_clear(Handle self, double x1, double y1, double x2, double y2) if ( !my->graphic_context_push(self)) return false; apc_gp_set_color(self, apc_gp_get_back_color(self)); apc_gp_set_fill_pattern(self, fillPatterns[fpSolid]); - ok = primitive( self, 1, "snnnn", "rectangle", x1, y1, x2, y2); + ok = Image_draw_primitive( self, 1, "snnnn", "rectangle", x1, y1, x2, y2); my->graphic_context_pop(self); return ok; } else { @@ -554,7 +553,7 @@ Image_clear(Handle self, double x1, double y1, double x2, double y2) COPY_MATRIX(identity, VAR_MATRIX); apc_gp_set_color(self, apc_gp_get_back_color(self)); apc_gp_set_fill_pattern(self, fillPatterns[fpSolid]); - ok = primitive( self, 1, "sS", "line", points ); + ok = Image_draw_primitive( self, 1, "sS", "line", points ); COPY_MATRIX(save, VAR_MATRIX); sv_free(points); my-> graphic_context_pop(self); @@ -571,35 +570,35 @@ Bool Image_ellipse( Handle self, double x, double y, double dX, double dY) { if ( opt_InPaint) return inherited ellipse(self, x, y, dX, dY); - return primitive( self, 0, "snnnn", "ellipse", x, y, dX, dY); + return Image_draw_primitive( self, 0, "snnnn", "ellipse", x, y, dX, dY); } Bool Image_fill_chord( Handle self, double x, double y, double dX, double dY, double startAngle, double endAngle) { if ( opt_InPaint) return inherited fill_chord(self, x, y, dX, dY, startAngle, endAngle); - return primitive( self, 1, "snnnnnn", "chord", x, y, dX, dY, startAngle, endAngle); + return Image_draw_primitive( self, 1, "snnnnnn", "chord", x, y, dX, dY, startAngle, endAngle); } Bool Image_fill_ellipse( Handle self, double x, double y, double dX, double dY) { if ( opt_InPaint) return inherited fill_ellipse(self, x, y, dX, dY); - return primitive( self, 1, "snnnn", "ellipse", x, y, dX, dY); + return Image_draw_primitive( self, 1, "snnnn", "ellipse", x, y, dX, dY); } Bool Image_fillpoly( Handle self, SV * points) { if ( opt_InPaint) return inherited fillpoly(self, points); - return primitive( self, 1, "sS", "line", points ); + return Image_draw_primitive( self, 1, "sS", "line", points ); } Bool Image_fill_sector( Handle self, double x, double y, double dX, double dY, double startAngle, double endAngle) { if ( opt_InPaint) return inherited fill_sector(self, x, y, dX, dY, startAngle, endAngle); - return primitive( self, 1, "snnnnnn", "sector", x, y, dX, dY, startAngle, endAngle); + return Image_draw_primitive( self, 1, "snnnnnn", "sector", x, y, dX, dY, startAngle, endAngle); } Bool @@ -636,7 +635,7 @@ Image_line(Handle self, double x1, double y1, double x2, double y2) prepare_line_context( self, lp, &ctx); return img_polyline(self, 2, poly, &ctx); } else { - return primitive( self, 0, "snnnn", "line", x1, y1, x2, y2); + return Image_draw_primitive( self, 0, "snnnn", "line", x1, y1, x2, y2); } } @@ -664,7 +663,7 @@ Image_lines( Handle self, SV * points) if (do_free) free(lines); return ok; } else { - return primitive( self, 0, "sS", "lines", points ); + return Image_draw_primitive( self, 0, "sS", "lines", points ); } } @@ -694,7 +693,7 @@ Image_polyline( Handle self, SV * points) free( lines ); return ok; } else { - return primitive( self, 0, "sS", "line", points ); + return Image_draw_primitive( self, 0, "sS", "line", points ); } } @@ -713,7 +712,7 @@ Image_rectangle(Handle self, double x1, double y1, double x2, double y2) prepare_line_context( self, lp, &ctx); return img_polyline(self, 5, dst, &ctx); } else { - return primitive( self, 0, "snnnn", "rectangle", x1, y1, x2, y2); + return Image_draw_primitive( self, 0, "snnnn", "rectangle", x1, y1, x2, y2); } } @@ -721,7 +720,7 @@ Bool Image_sector( Handle self, double x, double y, double dX, double dY, double startAngle, double endAngle) { if ( opt_InPaint) return inherited sector(self, x, y, dX, dY, startAngle, endAngle); - return primitive( self, 0, "snnnnnn", "sector", x, y, dX, dY, startAngle, endAngle); + return Image_draw_primitive( self, 0, "snnnnnn", "sector", x, y, dX, dY, startAngle, endAngle); } diff --git a/class/Image/text.c b/class/Image/text.c index e62586b3a..d7744a48f 100644 --- a/class/Image/text.c +++ b/class/Image/text.c @@ -201,7 +201,9 @@ plot_glyphs( Handle self, PGlyphsOutRec t, int x, int y ) COPY_MATRIX_WITHOUT_TRANSLATION( VAR_MATRIX, matrix); o.x += VAR_MATRIX[4]; o.y += VAR_MATRIX[5]; - } + } else + prima_matrix_set_identity(matrix); + for ( i = i2 = 0; i < t->len; i++, i2 += 2) { Byte *arena; @@ -261,6 +263,46 @@ plot_glyphs( Handle self, PGlyphsOutRec t, int x, int y ) } } + if ( var-> font.style & (fsUnderlined|fsStruckOut) ) { + if ( var-> font.underlineThickness <= 1 ) { + ctx.linePattern = lpSolid; + } else { + my-> graphic_context_push(self); + my-> set_lineWidth( self, var->font.underlineThickness ); + my-> set_lineEnd( self, sv_2mortal(newSViv(leRound)) ); + my-> set_linePattern( self, sv_2mortal(newSVpv("\1", PL_na)) ); + if ( flags & ggoMonochrome) + my-> set_antialias( self, false ); + } + + if ( var-> font.style & fsStruckOut ) { + Point poly[2]; + poly[0].x = x; + poly[1].x = x + advance; + poly[0].y = poly[1].y = y + (var-> font.ascent - var-> font.internalLeading) / 2; + prima_matrix_apply2_int_to_int( matrix, poly, poly, 2); + if ( var-> font.underlineThickness <= 1 ) + img_polyline(self, 2, poly, &ctx); + else + Image_draw_primitive( self, 0, "siiii", "line", poly[0].x, poly[0].y, poly[1].x, poly[1].y); + } + + if ( var-> font.style & fsUnderlined ) { + Point poly[2]; + poly[0].x = x; + poly[1].x = x + advance; + poly[0].y = poly[1].y = y + var-> font.underlinePosition; + prima_matrix_apply2_int_to_int( matrix, poly, poly, 2); + if ( var-> font.underlineThickness <= 1 ) + img_polyline(self, 2, poly, &ctx); + else + Image_draw_primitive( self, 0, "siiii", "line", poly[0].x, poly[0].y, poly[1].x, poly[1].y); + } + + if ( var-> font.underlineThickness > 1 ) + my-> graphic_context_pop(self); + } + if ( restore_font ) apc_gp_set_font( self, &var-> font); diff --git a/include/Image_private.h b/include/Image_private.h index 2a9718a7e..ab4ae8af7 100644 --- a/include/Image_private.h +++ b/include/Image_private.h @@ -29,6 +29,9 @@ Icon_create_from_image( Handle self, int maskType, SV * mask_fill ); Color Image_premultiply_color( Handle self, int rop, Color color); +Bool +Image_draw_primitive( Handle self, Bool fill, char * method, ...); + SV* Application_fonts( Handle self, char * name, char * encoding); diff --git a/win32/stock.c b/win32/stock.c index 51c6a4c55..aaa26ff7f 100644 --- a/win32/stock.c +++ b/win32/stock.c @@ -1135,8 +1135,8 @@ font_textmetric2font( TEXTMETRICW * tm, Font * fm, Bool readonly) void font_otm2font( OUTLINETEXTMETRICW * otm, Font * fm) { - fm-> underlinePosition = -otm->otmsUnderscorePosition; - fm-> underlineThickness = otm->otmsUnderscoreSize; + fm-> underlinePosition = otm->otmsUnderscorePosition; + fm-> underlineThickness = otm->otmsUnderscoreSize; } void @@ -1537,6 +1537,7 @@ font_font2gp( PFont font, Point res, Bool forceSize, HDC dc) memcpy( &key, font, sizeof( Font)); font_font2gp_internal( font, res, forceSize, dc); font-> resolution = res. y * 0x10000 + res. x; + memset( &font->undef, 0, sizeof(font->undef)); if ( forceSize) { key. height = font-> height; addSizeEntry = true; diff --git a/win32/text.c b/win32/text.c index 5a247b0c7..1bf2ba294 100644 --- a/win32/text.c +++ b/win32/text.c @@ -173,7 +173,7 @@ underscore_font( Handle self, int x, int y, int width, Bool use_alpha) if ( !is_apt( aptTextOutBaseline)) Y -= var font. descent; - Y += var font. underlinePosition; + Y -= var font. underlinePosition; pt[0].x = 0; pt[0].y = -Y; @@ -205,7 +205,7 @@ underscore_font( Handle self, int x, int y, int width, Bool use_alpha) if (sys otmsStrikeoutSize > 0) Y -= sys otmsStrikeoutPosition; else - Y -= var font. ascent / 2; + Y -= (var font. ascent - var font. internalLeading) / 2; pt[0].x = 0; pt[0].y = -Y;