Skip to content

Commit

Permalink
Image.text_out: implement fsUnderlined and fsStruckOut
Browse files Browse the repository at this point in the history
  • Loading branch information
dk committed Dec 10, 2023
1 parent 9fa8fa8 commit e2c901f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 26 deletions.
41 changes: 20 additions & 21 deletions class/Image/primitive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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 );
}
}

Expand Down Expand Up @@ -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 );
}
}

Expand All @@ -713,15 +712,15 @@ 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);
}
}

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);
}


Expand Down
44 changes: 43 additions & 1 deletion class/Image/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions include/Image_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions win32/stock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions win32/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit e2c901f

Please sign in to comment.