gdiplus: Switch to a struct for gdip_format_string callback args.
This commit is contained in:
parent
8a8d1dedcf
commit
f2c92c68a2
3 changed files with 82 additions and 78 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue