1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

gdiplus: Switch to a struct for gdip_format_string callback args.

This commit is contained in:
Esme Povirk 2024-02-23 19:48:59 +00:00 committed by Alexandre Julliard
parent 8a8d1dedcf
commit f2c92c68a2
3 changed files with 82 additions and 78 deletions

View file

@ -619,12 +619,22 @@ struct gdip_font_link_info {
struct list sections;
};
struct gdip_format_string_info {
GpGraphics *graphics;
GDIPCONST WCHAR *string;
INT index;
INT length;
struct gdip_font_link_info font_link_info;
GDIPCONST RectF *rect;
GDIPCONST GpStringFormat *format;
INT lineno;
const RectF *bounds;
INT *underlined_indexes;
INT underlined_index_count;
void *user_data;
};
typedef GpStatus (*gdip_format_string_callback)(GpGraphics *graphics,
GDIPCONST WCHAR *string, INT index, INT length, struct gdip_font_link_info *sections,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *user_data);
typedef GpStatus (*gdip_format_string_callback)(struct gdip_format_string_info *info);
GpStatus gdip_format_string(GpGraphics *graphics,
GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,

View file

@ -5318,17 +5318,26 @@ GpStatus gdip_format_string(GpGraphics *graphics,
INT *hotkeyprefix_offsets=NULL;
INT hotkeyprefix_count=0;
INT hotkeyprefix_pos=0, hotkeyprefix_end_pos=0;
struct gdip_font_link_info font_link_info = { 0 };
BOOL seen_prefix = FALSE, unixstyle_newline = TRUE;
struct gdip_format_string_info info;
info.graphics = graphics;
info.rect = rect;
info.bounds = &bounds;
info.user_data = user_data;
if(length == -1) length = lstrlenW(string);
stringdup = calloc(length + 1, sizeof(WCHAR));
if(!stringdup) return OutOfMemory;
info.string = stringdup;
if (!format)
format = &default_drawstring_format;
info.format = format;
nwidth = (int)(rect->Width + 0.005f);
nheight = (int)(rect->Height + 0.005f);
if (ignore_empty_clip)
@ -5384,10 +5393,10 @@ GpStatus gdip_format_string(GpGraphics *graphics,
halign = format->align;
generate_font_link_info(graphics, stringdup, length, font, &font_link_info);
generate_font_link_info(graphics, stringdup, length, font, &info.font_link_info);
while(sum < length){
font_link_get_text_extent_point(&font_link_info, graphics, stringdup, sum, length - sum, nwidth, &fit, &size);
font_link_get_text_extent_point(&info.font_link_info, graphics, stringdup, sum, length - sum, nwidth, &fit, &size);
fitcpy = fit;
if(fit == 0)
@ -5435,7 +5444,7 @@ GpStatus gdip_format_string(GpGraphics *graphics,
else
lineend = fit;
font_link_get_text_extent_point(&font_link_info, graphics, stringdup, sum, lineend, nwidth, &j, &size);
font_link_get_text_extent_point(&info.font_link_info, graphics, stringdup, sum, lineend, nwidth, &j, &size);
bounds.Width = size.cx;
@ -5468,10 +5477,13 @@ GpStatus gdip_format_string(GpGraphics *graphics,
if (hotkeyprefix_offsets[hotkeyprefix_end_pos] >= sum + lineend)
break;
stat = callback(graphics, stringdup, sum, lineend,
&font_link_info, rect, format, lineno, &bounds,
&hotkeyprefix_offsets[hotkeyprefix_pos],
hotkeyprefix_end_pos-hotkeyprefix_pos, user_data);
info.index = sum;
info.length = lineend;
info.lineno = lineno;
info.underlined_indexes = &hotkeyprefix_offsets[hotkeyprefix_pos];
info.underlined_index_count = hotkeyprefix_end_pos-hotkeyprefix_pos;
stat = callback(&info);
if (stat != Ok)
break;
@ -5500,7 +5512,7 @@ GpStatus gdip_format_string(GpGraphics *graphics,
break;
}
release_font_link_info(&font_link_info);
release_font_link_info(&info.font_link_info);
free(stringdup);
free(hotkeyprefix_offsets);
@ -5535,34 +5547,30 @@ struct measure_ranges_args {
REAL rel_width, rel_height;
};
static GpStatus measure_ranges_callback(GpGraphics *graphics,
GDIPCONST WCHAR *string, INT index, INT length,
struct gdip_font_link_info *font_link_info,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *user_data)
static GpStatus measure_ranges_callback(struct gdip_format_string_info *info)
{
int i;
GpStatus stat = Ok;
struct measure_ranges_args *args = user_data;
struct measure_ranges_args *args = info->user_data;
CharacterRange *ranges = info->format->character_ranges;
for (i=0; i<format->range_count; i++)
for (i=0; i < info->format->range_count; i++)
{
INT range_start = max(index, format->character_ranges[i].First);
INT range_end = min(index+length, format->character_ranges[i].First+format->character_ranges[i].Length);
INT range_start = max(info->index, ranges[i].First);
INT range_end = min(info->index + info->length, ranges[i].First + ranges[i].Length);
if (range_start < range_end)
{
GpRectF range_rect;
SIZE range_size;
range_rect.Y = bounds->Y / args->rel_height;
range_rect.Height = bounds->Height / args->rel_height;
range_rect.Y = info->bounds->Y / args->rel_height;
range_rect.Height = info->bounds->Height / args->rel_height;
font_link_get_text_extent_point(font_link_info, graphics, string, index, range_start - index, INT_MAX, NULL, &range_size);
range_rect.X = (bounds->X + range_size.cx) / args->rel_width;
font_link_get_text_extent_point(&info->font_link_info, info->graphics, info->string, info->index, range_start - info->index, INT_MAX, NULL, &range_size);
range_rect.X = (info->bounds->X + range_size.cx) / args->rel_width;
font_link_get_text_extent_point(font_link_info, graphics, string, index, range_end - index, INT_MAX, NULL, &range_size);
range_rect.Width = (bounds->X + range_size.cx) / args->rel_width - range_rect.X;
font_link_get_text_extent_point(&info->font_link_info, info->graphics, info->string, info->index, range_end - info->index, INT_MAX, NULL, &range_size);
range_rect.Width = (info->bounds->X + range_size.cx) / args->rel_width - range_rect.X;
stat = GdipCombineRegionRect(args->regions[i], &range_rect, CombineModeUnion);
if (stat != Ok)
@ -5659,18 +5667,13 @@ struct measure_string_args {
REAL rel_width, rel_height;
};
static GpStatus measure_string_callback(GpGraphics *graphics,
GDIPCONST WCHAR *string, INT index, INT length,
struct gdip_font_link_info *font_link_info,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *user_data)
static GpStatus measure_string_callback(struct gdip_format_string_info *info)
{
struct measure_string_args *args = user_data;
struct measure_string_args *args = info->user_data;
REAL new_width, new_height;
new_width = bounds->Width / args->rel_width;
new_height = (bounds->Height + bounds->Y) / args->rel_height - args->bounds->Y;
new_width = info->bounds->Width / args->rel_width;
new_height = (info->bounds->Height + info->bounds->Y) / args->rel_height - args->bounds->Y;
if (new_width > args->bounds->Width)
args->bounds->Width = new_width;
@ -5679,7 +5682,7 @@ static GpStatus measure_string_callback(GpGraphics *graphics,
args->bounds->Height = new_height;
if (args->codepointsfitted)
*args->codepointsfitted = index + length;
*args->codepointsfitted = info->index + info->length;
if (args->linesfilled)
(*args->linesfilled)++;
@ -5778,63 +5781,58 @@ struct draw_string_args {
REAL x, y, rel_width, rel_height, ascent;
};
static GpStatus draw_string_callback(GpGraphics *graphics,
GDIPCONST WCHAR *string, INT index, INT length,
struct gdip_font_link_info *font_link_info,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *user_data)
static GpStatus draw_string_callback(struct gdip_format_string_info *info)
{
struct draw_string_args *args = user_data;
int i = index;
struct draw_string_args *args = info->user_data;
int i = info->index;
PointF position;
SIZE size;
DWORD to_draw_length;
struct gdip_font_link_section *section;
GpStatus stat = Ok;
position.X = args->x + bounds->X / args->rel_width;
position.Y = args->y + bounds->Y / args->rel_height + args->ascent;
position.X = args->x + info->bounds->X / args->rel_width;
position.Y = args->y + info->bounds->Y / args->rel_height + args->ascent;
LIST_FOR_EACH_ENTRY(section, &font_link_info->sections, struct gdip_font_link_section, entry)
LIST_FOR_EACH_ENTRY(section, &info->font_link_info.sections, struct gdip_font_link_section, entry)
{
if (i >= section->end) continue;
to_draw_length = min(length - (i - index), section->end - i);
TRACE("index %d, todraw %ld, used %s\n", i, to_draw_length, section->font == font_link_info->base_font ? "base font" : "map");
font_link_get_text_extent_point(font_link_info, graphics, string, i, to_draw_length, 0, NULL, &size);
stat = draw_driver_string(graphics, &string[i], to_draw_length,
section->font, format, args->brush, &position,
to_draw_length = min(info->length - (i - info->index), section->end - i);
TRACE("index %d, todraw %ld, used %s\n", i, to_draw_length, section->font == info->font_link_info.base_font ? "base font" : "map");
font_link_get_text_extent_point(&info->font_link_info, info->graphics, info->string, i, to_draw_length, 0, NULL, &size);
stat = draw_driver_string(info->graphics, &info->string[i], to_draw_length,
section->font, info->format, args->brush, &position,
DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL);
position.X += size.cx / args->rel_width;
i += to_draw_length;
if (stat != Ok || (i - index) >= length) break;
if (stat != Ok || (i - info->index) >= info->length) break;
}
if (stat == Ok && underlined_index_count)
if (stat == Ok && info->underlined_index_count)
{
OUTLINETEXTMETRICW otm;
REAL underline_y, underline_height;
int i;
GetOutlineTextMetricsW(graphics->hdc, sizeof(otm), &otm);
GetOutlineTextMetricsW(info->graphics->hdc, sizeof(otm), &otm);
underline_height = otm.otmsUnderscoreSize / args->rel_height;
underline_y = position.Y - otm.otmsUnderscorePosition / args->rel_height - underline_height / 2;
for (i=0; i<underlined_index_count; i++)
for (i=0; i<info->underlined_index_count; i++)
{
REAL start_x, end_x;
SIZE text_size;
INT ofs = underlined_indexes[i] - index;
INT ofs = info->underlined_indexes[i] - info->index;
font_link_get_text_extent_point(font_link_info, graphics, string, index, ofs, INT_MAX, NULL, &text_size);
font_link_get_text_extent_point(&info->font_link_info, info->graphics, info->string, info->index, ofs, INT_MAX, NULL, &text_size);
start_x = text_size.cx / args->rel_width;
font_link_get_text_extent_point(font_link_info, graphics, string, index, ofs+1, INT_MAX, NULL, &text_size);
font_link_get_text_extent_point(&info->font_link_info, info->graphics, info->string, info->index, ofs+1, INT_MAX, NULL, &text_size);
end_x = text_size.cx / args->rel_width;
GdipFillRectangle(graphics, (GpBrush*)args->brush, position.X+start_x, underline_y, end_x-start_x, underline_height);
GdipFillRectangle(info->graphics, (GpBrush*)args->brush, position.X+start_x, underline_y, end_x-start_x, underline_height);
}
}

View file

@ -997,33 +997,29 @@ struct format_string_args
float ascent;
};
static GpStatus format_string_callback(GpGraphics *graphics,
GDIPCONST WCHAR *string, INT index, INT length, struct gdip_font_link_info *font_link_info,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *priv)
static GpStatus format_string_callback(struct gdip_format_string_info* info)
{
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
struct format_string_args *args = priv;
struct format_string_args *args = info->user_data;
GpPath *path = args->path;
GpStatus status = Ok;
float x = rect->X + (bounds->X - rect->X) * args->scale;
float y = rect->Y + (bounds->Y - rect->Y) * args->scale;
float x = info->rect->X + (info->bounds->X - info->rect->X) * args->scale;
float y = info->rect->Y + (info->bounds->Y - info->rect->Y) * args->scale;
int i;
if (underlined_index_count)
if (info->underlined_index_count)
FIXME("hotkey underlines not drawn yet\n");
if (y + bounds->Height * args->scale > args->maxY)
args->maxY = y + bounds->Height * args->scale;
if (y + info->bounds->Height * args->scale > args->maxY)
args->maxY = y + info->bounds->Height * args->scale;
for (i = index; i < length + index; ++i)
for (i = info->index; i < info->length + info->index; ++i)
{
GLYPHMETRICS gm;
TTPOLYGONHEADER *ph = NULL, *origph;
char *start;
DWORD len, ofs = 0;
len = GetGlyphOutlineW(graphics->hdc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
len = GetGlyphOutlineW(info->graphics->hdc, info->string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
if (len == GDI_ERROR)
{
status = GenericError;
@ -1037,7 +1033,7 @@ static GpStatus format_string_callback(GpGraphics *graphics,
status = OutOfMemory;
break;
}
GetGlyphOutlineW(graphics->hdc, string[i], GGO_BEZIER, &gm, len, start, &identity);
GetGlyphOutlineW(info->graphics->hdc, info->string[i], GGO_BEZIER, &gm, len, start, &identity);
ofs = 0;
while (ofs < len)