2007-01-16 Behdad Esfahbod <behdad@gnome.org>
+ *.c, *.h: Drop trailing whitespace.
+
+2007-01-16 Behdad Esfahbod <behdad@gnome.org>
+
Bug 328585 – Need to know if a layout has unknown glyphs
Patch from LingNing Zhang
/* Create a PangoLayout, set the font and text */
layout = pango_cairo_create_layout (cr);
-
+
pango_layout_set_text (layout, "Text", -1);
desc = pango_font_description_from_string (FONT);
pango_layout_set_font_description (layout, desc);
cairo_set_source_rgb (cr, red, 0, 1.0 - red);
cairo_rotate (cr, angle * G_PI / 180.);
-
+
/* Inform Pango to re-layout the text with the new transformation */
pango_cairo_update_layout (cr, layout);
-
+
pango_layout_get_size (layout, &width, &height);
cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - RADIUS);
pango_cairo_show_layout (cr, layout);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
2 * RADIUS, 2 * RADIUS);
cr = cairo_create (surface);
-
+
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_paint (cr);
draw_text (cr);
cairo_destroy (cr);
-
+
status = cairo_surface_write_to_png (surface, filename);
cairo_surface_destroy (surface);
current_path = cairo_copy_path (cr);
cairo_new_path (cr);
-
+
transform_path (current_path,
(transform_point_func_t) point_on_path, ¶m);
cairo_font_options_destroy (font_options);
layout = pango_cairo_create_layout (cr);
-
+
desc = pango_font_description_from_string (font);
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
/*path = cairo_copy_path (cr);*/
cairo_new_path (cr);
-
+
draw_text (cr, x, y, font, text);
map_path_onto (cr, path);
draw_wow (cr);
cairo_destroy (cr);
-
+
status = cairo_surface_write_to_png (surface, filename);
cairo_surface_destroy (surface);
static HDC pre_render (int width, int height);
static void post_render (HDC hdc, const char* sFile);
-static float
+static float
calc_duration (GTimeVal *tv1, GTimeVal *tv0)
{
return ( ((float)tv1->tv_sec - tv0->tv_sec)
family_name = g_strdup (pango_font_description_get_family (desc));
font = pango_font_map_load_font (fontmap, context, desc);
-
+
coverage = pango_font_get_coverage (font, lang);
/* ... */
g_get_current_time (&tv1);
g_print ("\tpango_font_map_load_font took %.3f sec\n", calc_duration (&tv1, &tv0));
- if (font)
+ if (font)
{
PangoItem *item;
PangoGlyphString * glyphs;
item->analysis.font = g_object_ref (font);
pango_shape ( s, sizeof(s), &(item->analysis), glyphs);
- if (hdc)
+ if (hdc)
{
/* the positioning isn't correct */
char* name = g_strdup_printf ("%s (%s%s)",
g_get_current_time (&tv0);
pango_win32_render (hdc, font, glyphs, 200, line);
g_get_current_time (&tv1);
- g_print ("\tpango_win32_render took %.3f sec\n",
+ g_print ("\tpango_win32_render took %.3f sec\n",
calc_duration (&tv1, &tv0));
line += (3 * my_font_size / 2);
g_free(name);
pango_glyph_string_free (glyphs);
pango_item_free (item);
- pango_coverage_unref (coverage);
+ pango_coverage_unref (coverage);
g_object_unref (font);
}
pango_font_description_free (desc);
WS_DISABLED,
0, 0, width, height,
GetDesktopWindow(),
- NULL,
+ NULL,
GetModuleHandle(NULL),
NULL);
DWORD cb; /* incremental count of bytes */
DWORD dwTmp;
HDC hDC;
-
+
pbih = (PBITMAPINFOHEADER) pbmi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits)
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
-
+
if (hf == INVALID_HANDLE_VALUE)
return FALSE;
hdr.bfType = 0x4d42; /* 0x42 = "B" 0x4d = "M" */
dwTotal = cb = pbih->biSizeImage;
if (!WriteFile(hf, (LPSTR) lpBits, (int) cb,
- (LPDWORD) &dwTotal, (LPOVERLAPPED) NULL))
+ (LPDWORD) &dwTotal, (LPOVERLAPPED) NULL))
return FALSE;
/* Close the .BMP file. */
if (!CloseHandle(hf))
return FALSE;
-
+
/* Free memory. */
GlobalFree((HGLOBAL)lpBits);
GlobalFree((HGLOBAL)pbmi);
DeleteDC(hDC);
} // C sucks
return TRUE;
-}
+}
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB,
tag, script_index, 0xffff, &feature_index))
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GPOS,
tag, script_index, 0xffff, &feature_index))
if (!ruleset_quark)
ruleset_quark = g_quark_from_string ("pango-arabic-ruleset");
-
+
if (!info)
return NULL;
swap_range (PangoGlyphString *glyphs, int start, int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
glyphs->log_clusters[i] = offset;
}
-static void
+static void
fallback_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
glong n_chars = g_utf8_strlen (text, length);
const char *p;
int i;
-
+
pango_glyph_string_set_size (glyphs, n_chars);
p = text;
-
+
for (i=0; i < n_chars; i++)
{
gunichar wc;
if (pango_get_mirror_char (wc, &mirrored_ch))
{
wc = mirrored_ch;
-
+
g_unichar_to_utf8 (wc, buf);
}
set_glyph (font, glyphs, i, p - text, index);
}
-
+
p = g_utf8_next_char (p);
}
if (glyphs->glyphs[i].glyph)
{
PangoRectangle logical_rect;
-
+
pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
glyphs->glyphs[i].geometry.width = logical_rect.width;
}
else
glyphs->glyphs[i].geometry.width = 0;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
}
-
+
if (analysis->level % 2 != 0)
{
/* Swap all glyphs */
}
}
-static void
+static void
arabic_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
buffer = pango_ot_buffer_new (fc_font);
pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0);
pango_ot_buffer_set_zero_width_marks (buffer, TRUE);
-
+
wcs = g_utf8_to_ucs4_fast (text, length, &n_chars);
properties = g_new0 (gulong, n_chars);
-
+
Arabic_Assign_Properties (wcs, properties, n_chars);
g_free (wcs);
-
+
p = text;
for (i=0; i < n_chars; i++)
{
if (pango_get_mirror_char (wc, &mirrored_ch))
{
wc = mirrored_ch;
-
+
g_unichar_to_utf8 (wc, buf);
}
if (wc == 0x6cc && ruleset && pango_fc_font_get_glyph (fc_font, 0x64a) &&
((properties[i] & (initial | medial)) != (initial | medial)))
wc = 0x64a;
-
+
index = pango_fc_font_get_glyph (fc_font, wc);
if (!index)
{
if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK)
cluster = p - text;
-
+
pango_ot_buffer_add_glyph (buffer, index,
properties[i], cluster);
}
}
-
+
p = g_utf8_next_char (p);
}
pango_ot_ruleset_substitute (ruleset, buffer);
pango_ot_ruleset_position (ruleset, buffer);
pango_ot_buffer_output (buffer, glyphs);
-
+
g_free (properties);
pango_ot_buffer_destroy (buffer);
PANGO_ENGINE_SHAPE_DEFINE_TYPE (ArabicEngineFc, arabic_engine_fc,
arabic_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
arabic_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
PANGO_ENGINE_LANG_DEFINE_TYPE (ArabicEngineLang, arabic_engine_lang,
arabic_engine_lang_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
arabic_engine_lang_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
*
* R7: If R1-R6 fail:
*
- * <anything> -> [isolated]
+ * <anything> -> [isolated]
*/
/* `direction' can be -1, 0, or 1 to indicate the last non-transparent
-/* Pango - Arabic module
+/* Pango - Arabic module
* arabic module
*
* (C) 2000 Karl Koehler<koehler@or.uni-bonn.de>
- * Owen Taylor <otaylor@redhat.com>
- *
+ * Owen Taylor <otaylor@redhat.com>
+ *
*/
#include <stdio.h>
#include "pango-engine.h"
#include "pangox.h"
-#include "arconv.h"
+#include "arconv.h"
#include "mulefont.h"
#include "langboxfont.h"
#include "naqshfont.h"
static ArabicFontInfo*
arabic_unicodeinit(PangoFont *font, PangoXSubfont subfont)
-{
+{
ArabicFontInfo *fs = NULL;
if (subfont != 0)
if ( pango_x_has_glyph /* Lam-Min alone */
(font,PANGO_X_MAKE_GLYPH(subfont,0xFC42)))
{
- fs->level |= ar_lig;
+ fs->level |= ar_lig;
/* extra ligatures in font, hopefully */
}
}
find_unic_font (PangoFont *font)
{
static char *charsets[] = {
- "iso10646-1",
+ "iso10646-1",
"iso8859-6.8x",
"mulearabic-2",
"urdunaqsh-0",
/* "symbol-0" */
};
-
+
ArabicFontInfo *fs = NULL;
PangoXSubfont *subfonts;
int *subfont_charsets;
int n_subfonts;
int i;
-
+
GQuark info_id = g_quark_from_string ("arabic-font-info");
fs = g_object_get_qdata (G_OBJECT (font), info_id);
if (fs) return fs;
- n_subfonts = pango_x_list_subfonts (font, charsets, 4,
+ n_subfonts = pango_x_list_subfonts (font, charsets, 4,
&subfonts, &subfont_charsets);
-
+
for (i=0; i < n_subfonts; i++)
{
if ( !strcmp (charsets[subfont_charsets[i]], "mulearabic-2"))
if (getenv("PANGO_AR_NOLBOXFONT") == NULL )
#endif
fs = arabic_lboxinit(font);
- }
+ }
else if ( !strcmp (charsets[subfont_charsets[i]], "urdunaqsh-0"))
{
#ifdef DEBUG
if (getenv("PANGO_AR_NONQFONT") == NULL )
#endif
fs = urdu_naqshinit(font);
- }
+ }
else
- {
+ {
#ifdef DEBUG
if (getenv("PANGO_AR_NOUNIFONT") == NULL )
#endif
fs = arabic_unicodeinit(font,subfonts[i]);
}
- if (fs){
- g_object_set_qdata_full (G_OBJECT (font), info_id,
+ if (fs){
+ g_object_set_qdata_full (G_OBJECT (font), info_id,
fs, (GDestroyNotify)g_free);
break;
}
static void
-set_glyph (PangoGlyphString *glyphs,
+set_glyph (PangoGlyphString *glyphs,
PangoFont *font, PangoXSubfont subfont,
int i, int cluster_start, int glyph, int is_vowel)
{
PangoRectangle logical_rect;
glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, glyph);
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
/* The following thing is actually critical ... */
-static void
-arabic_engine_shape (PangoFont *font,
+static void
+arabic_engine_shape (PangoFont *font,
const char *text,
int length,
- PangoAnalysis *analysis,
+ PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
PangoXSubfont subfont;
/* We hope there is a suitible font installed ..
*/
-
+
if (! (fs = find_unic_font (font)) )
{
PangoGlyph unknown_glyph = pango_x_get_unknown_glyph (font);
-
+
n_chars = g_utf8_strlen(text,length);
pango_glyph_string_set_size (glyphs, n_chars);
p = text;
for (i=0; i<n_chars; i++)
{
- set_glyph (glyphs, font,
- PANGO_X_GLYPH_SUBFONT (unknown_glyph), i,
+ set_glyph (glyphs, font,
+ PANGO_X_GLYPH_SUBFONT (unknown_glyph), i,
p - text, PANGO_X_GLYPH_INDEX (unknown_glyph),0);
p = g_utf8_next_char (p);
}
if (analysis->level % 2 == 0)
{
wc = g_utf8_to_ucs4_fast(text,length,&n_chars);
- /* We were called on a LTR directional run (e.g. some numbers);
+ /* We were called on a LTR directional run (e.g. some numbers);
fallback as simple as possible */
pango_glyph_string_set_size (glyphs, n_chars);
}
- else
+ else
{
wc = (gunichar *)g_malloc(sizeof(gunichar)* (length) ); /* length is succicient: all arabic chars use at
least 2 bytes in utf-8 encoding */
p = text;
pold = p;
- i = 0;
+ i = 0;
subfont = fs->subfonts[0];
while(i < n_chars)
p = g_utf8_next_char (p);
#ifdef DEBUG
fprintf(stderr,"NULL-character detected in generated string.!");
-#endif
+#endif
i++;
}
- else
- {
+ else
+ {
int cluster_start ;
int is_vowel = arabic_isvowel(wc[i]);
cluster_start = is_vowel ? pold - text : p - text;
&(wc[i+1]),
fs->subfonts);
}
- else
+ else
arabic_lbox_recode(&subfont,&(wc[i]),NULL,
fs->subfonts);
}
&(wc[i+1]),
fs->subfonts);
}
- else
+ else
urdu_naqsh_recode(&subfont,&(wc[i]),NULL,
fs->subfonts);
}
-
+
set_glyph(glyphs, font, subfont, n_chars - i - 1,
cluster_start, wc[i], is_vowel);
-
+
pold = p;
p = g_utf8_next_char (p);
i++;
arabic_engine_x_new ()
{
PangoEngineShape *result;
-
+
result = g_new (PangoEngineShape, 1);
result->engine.id = "ArabicScriptEngine";
#define MODULE_ENTRY(func) func
#endif
-void
+void
MODULE_ENTRY(script_engine_list) (PangoEngineInfo **engines, int *n_engines)
{
*engines = script_engines;
return NULL;
}
-void
+void
MODULE_ENTRY(script_engine_unload) (PangoEngine *engine)
{
}
{ PANGO_SCRIPT_SHAVIAN, "*" },
{ PANGO_SCRIPT_LINEAR_B, "*" },
{ PANGO_SCRIPT_UGARITIC, "*" },
-
+
{ PANGO_SCRIPT_COMMON, "" }
};
PangoRectangle logical_rect;
glyphs->glyphs[i].glyph = glyph;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->glyphs[i].geometry.width = logical_rect.width;
}
-static void
+static void
basic_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
err = ATSUCreateTextLayout (&text_layout);
err = ATSUSetTextPointerLocation (text_layout, utf16, 0, n16, n16);
-
+
err = ATSUCreateStyle(&style);
fontID = pango_cairo_atsui_font_get_atsu_font_id (cafont);
-
+
err = ATSUSetAttributes(style,
sizeof(styleTags) / sizeof(styleTags[0]),
styleTags, styleSizes, styleValues);
-
+
err = ATSUSetRunStyle(text_layout,
style, kATSUFromTextBeginning, kATSUToTextEnd);
-
+
err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout (text_layout, 0,
kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
(void *)&layout_records,
&glyph_count);
-
+
p = text;
pango_glyph_string_set_size (glyphs, glyph_count - 1);
{
gunichar wc;
gunichar mirrored_ch;
-
+
wc = g_utf8_get_char (p);
-
+
if (analysis->level % 2)
if (pango_get_mirror_char (wc, &mirrored_ch))
wc = mirrored_ch;
-
+
if (wc == 0xa0) /* non-break-space */
wc = 0x20;
-
+
if (pango_is_zero_width (wc))
{
set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);
else
{
set_glyph (font, glyphs, i, p - text, layout_records[i].glyphID);
-
+
if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
if (i > 0)
{
PangoRectangle logical_rect, ink_rect;
-
+
glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
glyphs->glyphs[i].geometry.width);
glyphs->glyphs[i-1].geometry.width = 0;
glyphs->log_clusters[i] = glyphs->log_clusters[i-1];
-
+
/* Some heuristics to try to guess how overstrike glyphs are
* done and compensate
*/
ATSUDirectReleaseLayoutDataArrayPtr (NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
(void *)&layout_records);
-
+
ATSUDisposeTextLayout (text_layout);
}
PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineATSUI, basic_engine_atsui,
basic_engine_atsui_class_init, NULL);
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
basic_engine_atsui_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
#include "pango-ot.h"
#include "basic-common.h"
-
+
/* No extra fields needed */
typedef PangoEngineShape BasicEngineFc;
typedef PangoEngineShapeClass BasicEngineFcClass;
/* Unicode-4.1 additions */
{ PANGO_SCRIPT_GLAGOLITIC, "*" },
-
+
/* Unicode-5.0 additions */
{ PANGO_SCRIPT_CUNEIFORM, "*" },
{ PANGO_SCRIPT_PHOENICIAN, "*" },
int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
PangoRectangle logical_rect;
glyphs->glyphs[i].glyph = glyph;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->glyphs[i].geometry.width = logical_rect.width;
}
-static void
+static void
fallback_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
glong n_chars = g_utf8_strlen (text, length);
const char *p;
int i;
-
+
pango_glyph_string_set_size (glyphs, n_chars);
p = text;
-
+
for (i=0; i < n_chars; i++)
{
gunichar wc;
if (pango_get_mirror_char (wc, &mirrored_ch))
{
wc = mirrored_ch;
-
+
g_unichar_to_utf8 (wc, buf);
}
else
{
set_glyph (font, glyphs, i, p - text, index);
-
+
if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
if (i > 0)
{
PangoRectangle logical_rect, ink_rect;
-
+
glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
glyphs->glyphs[i].geometry.width);
glyphs->glyphs[i-1].geometry.width = 0;
glyphs->log_clusters[i] = glyphs->log_clusters[i-1];
-
+
/* Some heuristics to try to guess how overstrike glyphs are
* done and compensate
*/
}
}
}
-
+
p = g_utf8_next_char (p);
}
if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GPOS, script_tag, &script_index))
for (j = 0; j < G_N_ELEMENTS (gpos_features); j++)
{
- PangoOTTag feature_tag = FT_MAKE_TAG (gpos_features[j][0], gpos_features[j][1],
+ PangoOTTag feature_tag = FT_MAKE_TAG (gpos_features[j][0], gpos_features[j][1],
gpos_features[j][2], gpos_features[j][3]);
guint feature_index;
if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GSUB, script_tag, &script_index))
for (j = 0; j < G_N_ELEMENTS (gsub_features); j++)
{
- PangoOTTag feature_tag = FT_MAKE_TAG (gsub_features[j][0], gsub_features[j][1],
+ PangoOTTag feature_tag = FT_MAKE_TAG (gsub_features[j][0], gsub_features[j][1],
gsub_features[j][2], gsub_features[j][3]);
guint feature_index;
/* 0xffff means default language */
- if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB, feature_tag,
+ if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB, feature_tag,
script_index, 0xffff, &feature_index))
{
pango_ot_ruleset_add_feature (ruleset, PANGO_OT_TABLE_GSUB, feature_index, 0xffff);
}
}
- }
+ }
g_object_set_qdata_full (G_OBJECT (info), ruleset_quark, ruleset, (GDestroyNotify) g_object_unref);
}
}
-static void
+static void
basic_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
if (pango_get_mirror_char (wc, &mirrored_ch))
{
wc = mirrored_ch;
-
+
g_unichar_to_utf8 (wc, buf);
}
else
{
index = pango_fc_font_get_glyph (fc_font, wc);
-
+
if (!index)
{
pango_ot_buffer_add_glyph (buffer, PANGO_GET_UNKNOWN_GLYPH ( wc),
{
if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK)
cluster = p - text;
-
+
pango_ot_buffer_add_glyph (buffer, index,
unknown_property, cluster);
}
}
-
+
p = g_utf8_next_char (p);
}
pango_ot_ruleset_substitute (ruleset, buffer);
pango_ot_ruleset_position (ruleset, buffer);
pango_ot_buffer_output (buffer, glyphs);
-
+
pango_ot_buffer_destroy (buffer);
out:
PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineFc, basic_engine_fc,
basic_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
basic_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
}
};
-static PangoGlyph
+static PangoGlyph
find_char (PangoFont *font,
gunichar wc)
{
PangoRectangle logical_rect;
glyphs->glyphs[i].glyph = glyph;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
lang_name (int lang)
{
static char unk[10];
-
+
switch (PRIMARYLANGID (lang))
{
#define CASE(n) case LANG_##n: return #n
g_assert (glyphs->log_clusters[glyphix] < n_chars);
glyphs->log_clusters[glyphix] = byte_offset[glyphs->log_clusters[glyphix]];
}
-
+
g_free (byte_offset);
}
control.uDefaultLanguage = make_langid (analysis->language);
state.uBidiLevel = analysis->level;
-
+
#ifdef BASIC_WIN32_DEBUGGING
if (pango_win32_debug)
g_print (G_STRLOC ": ScriptItemize: uDefaultLanguage:%04x uBidiLevel:%d\n",
memset (advances, 0, sizeof (advances));
memset (offsets, 0, sizeof (offsets));
memset (&abc, 0, sizeof (abc));
-
+
/* Note that itemlen is number of wchar_t's i.e. surrogate pairs
* count as two!
*/
#endif
return FALSE;
}
-
+
#ifdef BASIC_WIN32_DEBUGGING
dump_glyphs_and_log_clusters (items[item].a.fRTL, itemlen,
items[item].iCharPos, log_clusters,
ng = glyphs->num_glyphs;
pango_glyph_string_set_size (glyphs, ng + nglyphs);
-
+
set_up_pango_log_clusters (wtext,
items[item].a.fRTL, itemlen, log_clusters,
nglyphs, glyphs->log_clusters + ng,
if (script_cache[i])
(*script_free_cache)(&script_cache[i]);
}
-
+
if (retval)
{
convert_log_clusters_to_byte_offsets (text, length, glyphs);
return retval;
}
-
+
#endif /* HAVE_USP10_H */
-static void
+static void
basic_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
if (wc == 0xa0) /* non-break-space */
wc = 0x20;
-
+
if (pango_is_zero_width (wc))
{
set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);
if (index)
{
set_glyph (font, glyphs, i, p - text, index);
-
+
if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
if (i > 0)
{
PangoRectangle logical_rect, ink_rect;
-
+
glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
glyphs->glyphs[i].geometry.width);
glyphs->glyphs[i-1].geometry.width = 0;
else
set_glyph (font, glyphs, i, p - text, PANGO_GET_UNKNOWN_GLYPH (wc));
}
-
+
p = g_utf8_next_char (p);
}
/* Swap all glyphs */
swap_range (glyphs, 0, n_chars);
-
+
/* Now reorder glyphs within each cluster back to LTR */
for (start = 0; start < n_chars;)
{
while (end < n_chars &&
glyphs->log_clusters[end] == glyphs->log_clusters[start])
end++;
-
+
swap_range (glyphs, start, end);
start = end;
}
HMODULE usp10_dll;
have_uniscribe = FALSE;
-
+
if ((usp10_dll = LoadLibrary ("usp10.dll")) != NULL)
{
(script_get_properties = (pScriptGetProperties)
hdc = pango_win32_get_dc ();
}
#endif
-}
+}
static void
basic_engine_win32_class_init (PangoEngineShapeClass *class)
PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineWin32, basic_engine_win32,
basic_engine_win32_class_init, NULL);
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
init_uniscribe ();
basic_engine_win32_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
guint16 charsets;
};
-struct _MaskTable
+struct _MaskTable
{
int n_subfonts;
Charset **charsets;
};
-struct _CharCache
+struct _CharCache
{
guint ref_count;
CharsetOrdering *ordering;
* PangoFont => CharCachePointer ===\
* | \
* CharCachePointer ======> CharCache => CharsetOrdering
- * | |======> MaskTable[0] => {subfonts,charset}[n_subfonts],
- * | |======> MaskTable[1] => {subfonts,charset}[n_subfonts],
+ * | |======> MaskTable[0] => {subfonts,charset}[n_subfonts],
+ * | |======> MaskTable[1] => {subfonts,charset}[n_subfonts],
* | \======> MaskTable[...] => {subfonts,charset}[n_subfonts]
* |
* CharCachePointer ======> CharCache => CharsetOrdering
- * |======> MaskTable[0] => {subfonts,charset}[n_subfonts],
- * |======> MaskTable[1] => {subfonts,charset}[n_subfonts],
+ * |======> MaskTable[0] => {subfonts,charset}[n_subfonts],
+ * |======> MaskTable[1] => {subfonts,charset}[n_subfonts],
* \======> MaskTable[...] => {subfonts,charset}[n_subfonts]
- *
+ *
* A CharCache structure caches the lookup of what subfonts can be used for what characters for a pair of a Font
* and CharsetOrdering. Multiple language tags can share the same CharsetOrdering - the list of CharCachePointer
* structures that is attached to the font as object data provides lookups from language tag to charcache.
result->ordering = ordering;
for (i=0; i<MAX_CHARSETS; i++)
result->converters[i] = (GIConv)-1;
-
+
return result;
}
{
g_free (cache->mask_tables[i]->subfonts);
g_free (cache->mask_tables[i]->charsets);
-
+
g_free (cache->mask_tables[i]);
}
for (i=0; i<MAX_CHARSETS; i++)
if (cache->converters[i] != (GIConv)-1)
g_iconv_close (cache->converters[i]);
-
+
g_free (cache);
}
-static PangoGlyph
+static PangoGlyph
find_char (CharCache *cache, PangoFont *font, gunichar wc, const char *input)
{
int mask_index;
return PANGO_GET_UNKNOWN_GLYPH (wc);
break;
}
-
+
if (wc >= G_N_ELEMENTS (char_masks))
mask_index = 0;
else
for (i=0; i<(int)G_N_ELEMENTS(charsets); i++)
{
int charset_index = cache->ordering->charsets[i];
-
+
if (mask & (1 << charset_index))
{
charset_names[n_charsets] = charsets[charset_index].x_charset;
charsets_map[n_charsets] = &charsets[charset_index];
-
+
n_charsets++;
}
}
-
+
mask_table->n_subfonts = pango_x_list_subfonts (font, (char**)charset_names, n_charsets, &mask_table->subfonts, &subfont_charsets);
mask_table->charsets = g_new (Charset *, mask_table->n_subfonts);
mask_table->charsets[i] = NULL;
continue;
}
-
- cache->converters[charset->index] = cd;
+
+ cache->converters[charset->index] = cd;
}
-
+
index = (*charset->conv_func) (cache, cd, input);
glyph = PANGO_X_MAKE_GLYPH (mask_table->subfonts[i], index);
if (pango_x_has_glyph (font, glyph))
- return glyph;
+ return glyph;
}
}
PangoRectangle logical_rect;
glyphs->glyphs[i].glyph = glyph;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
const char *input)
{
char outbuf;
-
+
const char *inptr = input;
size_t inbytesleft;
char *outptr = &outbuf;
size_t outbytesleft = 1;
inbytesleft = g_utf8_next_char (input) - input;
-
+
g_iconv (cd, (char **)&inptr, &inbytesleft, &outptr, &outbytesleft);
return (guchar)outbuf;
size_t outbytesleft = 4;
inbytesleft = g_utf8_next_char (input) - input;
-
+
g_iconv (cd, (char **)&inptr, &inbytesleft, &outptr, &outbytesleft);
if ((guchar)outbuf[0] < 128)
size_t outbytesleft = 2;
inbytesleft = g_utf8_next_char (input) - input;
-
+
g_iconv (cd, (char **)&inptr, &inbytesleft, &outptr, &outbytesleft);
if ((guchar)outbuf[0] < 128)
size_t outbytesleft = 2;
inbytesleft = g_utf8_next_char (input) - input;
-
+
g_iconv (cd, (char **)&inptr, &inbytesleft, &outptr, &outbytesleft);
if ((guchar)outbuf[0] < 128)
inbytesleft = g_utf8_next_char (input) - input;
-
+
g_iconv (cd, (char **)&inptr, &inbytesleft, &outptr, &outbytesleft);
if ((guchar)outbuf[0] < 128)
size_t outbytesleft = 4;
inbytesleft = g_utf8_next_char (input) - input;
-
+
g_iconv (cd, (char **)&inptr, &inbytesleft, &outptr, &outbytesleft);
/* The first two bytes determine which page of CNS to use; we
swap_range (PangoGlyphString *glyphs, int start, int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
while (tmp_list)
{
CharCachePointer *pointer = tmp_list->data;
-
+
pointer->cache->ref_count--;
if (pointer->cache->ref_count == 0)
char_cache_free (pointer->cache);
g_free (pointer);
-
+
tmp_list = tmp_list->next;
}
g_slist_free (caches);
if (pango_language_matches (lang, charset_orderings[i].langs))
return &charset_orderings[i];
}
-
+
return &charset_orderings[i];
}
pointer->cache = cache;
caches = g_slist_prepend (caches, pointer);
-
+
g_object_steal_qdata (G_OBJECT (font), cache_id);
- g_object_set_qdata_full (G_OBJECT (font), cache_id,
+ g_object_set_qdata_full (G_OBJECT (font), cache_id,
caches, (GDestroyNotify)char_caches_free);
return cache;
}
-static void
+static void
basic_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
const char *input;
wc = g_utf8_get_char (p);
-
+
input = p;
if (analysis->level % 2)
if (pango_get_mirror_char (wc, &mirrored_ch))
{
wc = mirrored_ch;
-
+
g_unichar_to_utf8 (wc, buf);
input = buf;
}
if (wc == 0xa0) /* non-break-space */
{
wc = 0x20;
-
+
g_unichar_to_utf8 (wc, buf);
input = buf;
}
-
+
if (pango_is_zero_width (wc))
{
set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);
if (index)
{
set_glyph (font, glyphs, i, p - text, index);
-
+
if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
if (i > 0)
{
PangoRectangle logical_rect, ink_rect;
-
+
glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
glyphs->glyphs[i].geometry.width);
glyphs->glyphs[i-1].geometry.width = 0;
else
set_glyph (font, glyphs, i, p - text, PANGO_GET_UNKNOWN_GLYPH (wc));
}
-
+
p = g_utf8_next_char (p);
}
/* Swap all glyphs */
swap_range (glyphs, 0, n_chars);
-
+
/* Now reorder glyphs within each cluster back to LTR */
for (start=0; start<n_chars;)
{
while (end < n_chars &&
glyphs->log_clusters[end] == glyphs->log_clusters[start])
end++;
-
+
swap_range (glyphs, start, end);
start = end;
}
PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineX, basic_engine_x,
basic_engine_x_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
basic_engine_x_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
/* Add a Hangul tone mark glyph in a glyph string.
* Non-spacing glyph works pretty much automatically.
* Spacing-glyph takes some care:
- * 1. Make a room for a tone mark at the beginning(leftmost end) of a cluster
+ * 1. Make a room for a tone mark at the beginning(leftmost end) of a cluster
* to attach it to.
* 2. Adjust x_offset so that it is drawn to the left of a cluster.
- * 3. Set the logical width to zero.
+ * 3. Set the logical width to zero.
*/
static void
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->log_clusters[i] = offset;
- pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph,
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph,
&ink_rect, &logical_rect);
- /* tone mark is not the first in a glyph string. We have info. on the
- * preceding glyphs in a glyph string
+ /* tone mark is not the first in a glyph string. We have info. on the
+ * preceding glyphs in a glyph string
*/
{
int j = i - 1;
/* search for the beg. of the preceding cluster */
- while (j >= 0 && glyphs->log_clusters[j] == glyphs->log_clusters[i - 1])
+ while (j >= 0 && glyphs->log_clusters[j] == glyphs->log_clusters[i - 1])
j--;
- /* In .._extents_range(...,start,end,...), to my surprise start is
- * inclusive but end is exclusive !!
+ /* In .._extents_range(...,start,end,...), to my surprise start is
+ * inclusive but end is exclusive !!
*/
- pango_glyph_string_extents_range (glyphs, j + 1, i, font,
- NULL, &logical_rect_cluster);
+ pango_glyph_string_extents_range (glyphs, j + 1, i, font,
+ NULL, &logical_rect_cluster);
/* logical_rect_cluster.width is all the offset we need so that the
* inherent x_offset in the glyph (ink_rect.x) should be canceled out.
*/
glyphs->glyphs[i].geometry.x_offset = - logical_rect_cluster.width
- - ink_rect.x ;
-
+ - ink_rect.x ;
+
/* make an additional room for a tone mark if it has a spacing glyph
- * because that's likely to be an indication that glyphs for other
+ * because that's likely to be an indication that glyphs for other
* characters in the font are not designed for combining with tone marks.
*/
if (logical_rect.width)
{
set_glyph_tone (font, glyphs, *n_glyphs, cluster_offset, index);
}
- else
+ else
{
/* fall back : HTONE1(0x302e) => middle-dot, HTONE2(0x302f) => colon */
index = find_char (font, tone == HTONE1 ? 0x00b7 : 0x003a);
{
set_glyph_tone (font, glyphs, *n_glyphs, cluster_offset, index);
}
- else
+ else
set_glyph (font, glyphs, *n_glyphs, cluster_offset,
PANGO_GET_UNKNOWN_GLYPH (tone));
}
* I have seen no smart font which can render S+T as a syllable
* form.
*/
-
+
if (length == 3 || length == 4)
{
p = str;
if (length == 4 && !IS_M(g_utf8_get_char(g_utf8_next_char(p))))
goto lvt_out; /* draw the tone mark later */
-
+
if (IS_L_S(text[0]) && IS_V_S(text[1]) && IS_T_S(text[2]))
{
composed = 3;
(*n_glyphs)++;
}
-static void
+static void
hangul_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
PANGO_ENGINE_SHAPE_DEFINE_TYPE (HangulEngineFc, hangul_engine_fc,
hangul_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
hangul_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
PangoRectangle logical_rect;
gunichar wc = cluster[i];
gunichar mirrored_ch;
-
+
if (do_mirror)
if (pango_get_mirror_char (wc, &mirrored_ch))
wc = mirrored_ch;
pango_font_get_glyph_extents (font,
glyph[i], &ink_rects[i], &logical_rect);
-
+
/* Assign the base char width to the last character in the cluster */
if (i==0)
{
}
static void
-add_glyph (PangoGlyphString *glyphs,
- gint cluster_start,
+add_glyph (PangoGlyphString *glyphs,
+ gint cluster_start,
PangoGlyph glyph,
gboolean is_combining,
gint width,
gint index = glyphs->num_glyphs;
pango_glyph_string_set_size (glyphs, index + 1);
-
+
glyphs->glyphs[index].glyph = glyph;
glyphs->glyphs[index].attr.is_cluster_start = is_combining ? 0 : 1;
-
+
glyphs->log_clusters[index] = cluster_start;
glyphs->glyphs[index].geometry.x_offset = x_offset;
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB,
tag, script_index, 0xffff, &feature_index))
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GPOS,
tag, script_index, 0xffff, &feature_index))
if (!ruleset_quark)
ruleset_quark = g_quark_from_string ("pango-hebrew-ruleset");
-
+
if (!info)
return NULL;
return ruleset;
}
-static void
+static void
fallback_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
glyph,
glyph_width,
ink_rects);
-
+
/* Kern the glyphs! */
hebrew_shaper_get_cluster_kerning(cluster,
cluster_size,
/* output */
x_offset,
y_offset);
-
+
add_cluster(font,
glyphs,
cluster_size,
glyph_width,
x_offset,
y_offset);
-
+
}
if (analysis->level % 2)
hebrew_shaper_bidi_reorder(glyphs);
}
-static void
+static void
hebrew_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
buffer = pango_ot_buffer_new (fc_font);
pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0);
-
+
n_chars = g_utf8_strlen (text, length);
-
+
p = text;
for (i=0; i < n_chars; i++)
{
if (pango_get_mirror_char (wc, &mirrored_ch))
{
wc = mirrored_ch;
-
+
g_unichar_to_utf8 (wc, buf);
}
else
{
index = pango_fc_font_get_glyph (fc_font, wc);
-
+
if (!index)
{
pango_ot_buffer_add_glyph (buffer, PANGO_GET_UNKNOWN_GLYPH ( wc),
else
{
cluster = p - text;
-
+
pango_ot_buffer_add_glyph (buffer, index,
unknown_property, cluster);
}
}
-
+
p = g_utf8_next_char (p);
}
-
+
pango_ot_ruleset_substitute (ruleset, buffer);
pango_ot_ruleset_position (ruleset, buffer);
pango_ot_buffer_output (buffer, glyphs);
pango_ot_buffer_destroy (buffer);
-
+
out:
pango_fc_font_unlock_face (fc_font);
}
PANGO_ENGINE_SHAPE_DEFINE_TYPE (HebrewEngineFc, hebrew_engine_fc,
hebrew_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
hebrew_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
*
* Hebrew points positioning improvements 2001
* Author: Dov Grobgeld <dov@imagic.weizmann.ac.il>
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
/*00*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
-
+
/*10*/ _ND, _NS, _NS, _NS, _NS, _NS, _NS, _NS,
_NS, _NS, _NS, _NS, _NS, _NS, _NS, _NS,
/*20*/ _NS, _NS, _ND, _NS, _NS, _NS, _NS, _NS,
/*00*/ __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND,
__ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND,
-
+
/*10*/ __ND, __NS, __NS, __NS, __NS, __NS, __NS, __NS,
__NS, __NS, __NS, __NS, __NS, __NS, __NS, __NS,
/*20*/ __NS, __NS, __ND, __NS, __NS, __NS, __NS, __NS,
gint length,
gunichar *cluster,
gint *num_chrs)
-{
+{
const char *p;
gint n_chars = 0;
-
+
p = text;
- while (p < text + length && n_chars < MAX_CLUSTER_CHRS)
+ while (p < text + length && n_chars < MAX_CLUSTER_CHRS)
{
gunichar current = g_utf8_get_char (p);
-
+
if (!ishebrew (current) ||
(n_chars == 0 && is_char_class(current, ~(NoDefine|SpacingLetter))))
{
/* Not a legal Hebrew cluster */
-
+
if (n_chars == 0)
{
cluster[n_chars++] = current;
x_offset[0] = -ink_rect[0].x - ink_rect[0].width;
width[0] = 0;
}
-
+
return;
}
int gl = cluster[i];
x_offset[i] = 0;
y_offset[i] = 0;
-
+
/* Check if it is a point */
if (gl < 0x5B0 || gl >= 0x05D0)
continue;
-
+
/* Center dot of VAV */
if (gl == UNI_MAPIQ && base_char == UNI_VAV)
- {
+ {
x_offset[i] = base_ink_x_offset - ink_rect[i].x;
/* If VAV is a vertical bar without a roof, then we
/* Dot over SHIN */
else if (gl == UNI_SHIN_DOT && base_char == UNI_SHIN)
- {
+ {
x_offset[i] = base_ink_x_offset + base_ink_width
- ink_rect[i].x - ink_rect[i].width;
}
-
+
/* Dot over SIN */
else if (gl == UNI_SIN_DOT && base_char == UNI_SHIN)
- {
+ {
x_offset[i] = base_ink_x_offset - ink_rect[i].x;
}
SHIN or VAV should stick out a bit to the left. */
else if ((gl == UNI_SIN_DOT || gl == UNI_HOLAM)
&& base_char != UNI_SHIN && base_char != UNI_VAV)
- {
+ {
x_offset[i] = base_ink_x_offset -ink_rect[i].x - ink_rect[i].width * 3/ 2;
}
-
+
/* VOWELS under resh or vav are right aligned, if they are
narrower than the characters. Otherwise they are centered.
*/
&& ((gl >= UNI_SHEVA && gl <= UNI_QAMATS) ||
gl == UNI_QUBUTS)
&& ink_rect[i].width < base_ink_width
- )
+ )
{
x_offset[i] = base_ink_x_offset + base_ink_width
- ink_rect[i].x - ink_rect[i].width;
else if ((base_char == UNI_FINAL_KAF
)
&& ((gl >= UNI_SHEVA && gl <= UNI_QAMATS) ||
- gl == UNI_QUBUTS))
+ gl == UNI_QUBUTS))
{
/* x are at 1/3 to take into accoun the stem */
x_offset[i] = base_ink_x_offset - ink_rect[i].x
+ base_ink_height * 1/2 - ink_rect[i].height/2;
}
-
+
/* MAPIQ in PE or FINAL PE */
else if (gl == UNI_MAPIQ
&& (base_char == UNI_PE || base_char == UNI_FINAL_PE))
{
x_offset[i]= base_ink_x_offset - ink_rect[i].x
+ base_ink_width * 2/3 - ink_rect[i].width/2;
-
+
/* Another option is to offset the MAPIQ in y...
glyphs->glyphs[cluster_start_idx+i].geometry.y_offset
-= base_ink_height/5; */
&& base_char == UNI_YOD)
{
x_offset[i]= base_ink_x_offset - ink_rect[i].x;
-
+
/* Lower left in y */
y_offset[i] = base_ink_y_offset - ink_rect[i].y
+ base_ink_height - ink_rect[i].height*1.75;
width[cluster_length-1] += ink_rect[i].width*(1+space-kern);
}
-
+
}
/* VOWEL DOT next to any other character */
else if ((gl == UNI_SIN_DOT || gl == UNI_HOLAM)
&& (base_char != UNI_VAV))
- {
+ {
x_offset[i] = base_ink_x_offset -ink_rect[i].x;
}
/* Center by default */
else
- {
+ {
x_offset[i] = base_ink_x_offset - ink_rect[i].x
+ base_ink_width/2 - ink_rect[i].width/2;
}
}
-
+
}
void
int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
hebrew_shaper_bidi_reorder(PangoGlyphString *glyphs)
{
int start, end;
-
+
/* Swap all glyphs */
hebrew_shaper_swap_range (glyphs, 0, glyphs->num_glyphs);
-
+
/* Now reorder glyphs within each cluster back to LTR */
for (start = 0; start < glyphs->num_glyphs;)
{
while (end < glyphs->num_glyphs &&
glyphs->log_clusters[end] == glyphs->log_clusters[start])
end++;
-
+
hebrew_shaper_swap_range (glyphs, start, end);
start = end;
}
struct _PangoIndicInfo
{
- PangoOTTag scriptTag;
+ PangoOTTag scriptTag;
const IndicOTClassTable *classTable;
const gchar *gsubQuarkName;
const gchar *gposQuarkName;
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB,
feature_tag, script_index, 0xffff, &feature_index))
/* analysis->shape_engine has the PangoEngine... */
-static void
+static void
indic_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
indic_info = indic_shape_engine->indicInfo;
wc_in = expand_text (text, length, &utf8_offsets, &n_chars);
-
+
n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL, NULL);
-
+
wc_out = g_new (gunichar, n_glyphs);
indices = g_new (glong, n_glyphs);
tags = g_new (gulong, n_glyphs);
n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags, &mprefixups);
-
+
pango_glyph_string_set_size (glyphs, n_glyphs);
buffer = pango_ot_buffer_new (fc_font);
PANGO_ENGINE_SHAPE_DEFINE_TYPE (IndicEngineFc, indic_engine_fc,
indic_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
indic_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
{
IndicEngineFc *engine = g_object_new (indic_engine_fc_type, NULL);
engine->indicInfo = &indic_info[i];
-
+
return (PangoEngine *)engine;
}
}
attrs[i].is_mandatory_break = FALSE;
}
else if (prev_wc != 0 && (this_wc == 0x200D || this_wc == 0x200C))
- {
+ {
if (next_wc != 0)
{
if (next_next_wc == 0)
attrs[i].is_cursor_position = FALSE;
attrs[i].is_char_break = FALSE;
attrs[i].is_line_break = FALSE;
- attrs[i].is_mandatory_break = FALSE;
+ attrs[i].is_mandatory_break = FALSE;
}
else if ((next_next_wc != 0) &&
(next_wc == 0x09CD || /* Bengali */
attrs[i].is_cursor_position = FALSE;
attrs[i].is_char_break = FALSE;
attrs[i].is_line_break = FALSE;
- attrs[i].is_mandatory_break = FALSE;
+ attrs[i].is_mandatory_break = FALSE;
- i++;
+ i++;
attrs[i].is_cursor_position = FALSE;
- }
+ }
}
- else
+ else
{
attrs[i].is_cursor_position = FALSE;
attrs[i].is_char_break = FALSE;
attrs[i].is_line_break = FALSE;
attrs[i].is_mandatory_break = FALSE;
- }
+ }
}
}
}
};
static const IndicOTCharClass oryaCharClasses[] =
-{
+{
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, /* 0B00 - 0B0F */
_iv, _xx, _xx, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _ct, _bb, /* 0B10 - 0B1F */
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _pb, /* 0B20 - 0B2F */
state = stateTable[state][char_class & CF_CLASS_MASK];
- /*for the components of split matra*/
+ /*for the components of split matra*/
if ((char_count >= cursor + 3) &&
(chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DCF && chars[cursor + 2] == 0x0DCA)) { /*for 3 split matra of Sinhala*/
return cursor + 3;
- }
+ }
else if ((char_count >= cursor + 3) &&
(chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CC2 && chars[cursor + 2] == 0x0CD5)) { /*for 3 split matra of Kannada*/
return cursor + 3;
}
- /*for 2 split matra*/
+ /*for 2 split matra*/
else if (char_count >= cursor + 2) {
/*for Bengali*/
- if ((chars[cursor] == 0x09C7 && chars[cursor + 1] == 0x09BE) ||
- (chars[cursor] == 0x09C7 && chars[cursor + 1] == 0x09D7) ||
+ if ((chars[cursor] == 0x09C7 && chars[cursor + 1] == 0x09BE) ||
+ (chars[cursor] == 0x09C7 && chars[cursor + 1] == 0x09D7) ||
/*for Oriya*/
- (chars[cursor] == 0x0B47 && chars[cursor + 1] == 0x0B3E) ||
- (chars[cursor] == 0x0B47 && chars[cursor + 1] == 0x0B56) ||
+ (chars[cursor] == 0x0B47 && chars[cursor + 1] == 0x0B3E) ||
+ (chars[cursor] == 0x0B47 && chars[cursor + 1] == 0x0B56) ||
(chars[cursor] == 0x0B47 && chars[cursor + 1] == 0x0B57) ||
/*for Tamil*/
- (chars[cursor] == 0x0BC6 && chars[cursor + 1] == 0x0BBE) ||
- (chars[cursor] == 0x0BC6 && chars[cursor + 1] == 0x0BD7) ||
- (chars[cursor] == 0x0BC7 && chars[cursor + 1] == 0x0BBE) ||
+ (chars[cursor] == 0x0BC6 && chars[cursor + 1] == 0x0BBE) ||
+ (chars[cursor] == 0x0BC6 && chars[cursor + 1] == 0x0BD7) ||
+ (chars[cursor] == 0x0BC7 && chars[cursor + 1] == 0x0BBE) ||
/*for Malayalam*/
- (chars[cursor] == 0x0D46 && chars[cursor + 1] == 0x0D3E) ||
- (chars[cursor] == 0x0D46 && chars[cursor + 1] == 0x0D57) ||
- (chars[cursor] == 0x0D47 && chars[cursor + 1] == 0x0D3E) ||
+ (chars[cursor] == 0x0D46 && chars[cursor + 1] == 0x0D3E) ||
+ (chars[cursor] == 0x0D46 && chars[cursor + 1] == 0x0D57) ||
+ (chars[cursor] == 0x0D47 && chars[cursor + 1] == 0x0D3E) ||
/*for Sinhala*/
- (chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DCA) ||
- (chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DCF) ||
- (chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DDF) ||
- (chars[cursor] == 0x0DDC && chars[cursor + 1] == 0x0DCA) ||
+ (chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DCA) ||
+ (chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DCF) ||
+ (chars[cursor] == 0x0DD9 && chars[cursor + 1] == 0x0DDF) ||
+ (chars[cursor] == 0x0DDC && chars[cursor + 1] == 0x0DCA) ||
/*for Telugu*/
- (chars[cursor] == 0x0C46 && chars[cursor + 1] == 0x0C56) ||
+ (chars[cursor] == 0x0C46 && chars[cursor + 1] == 0x0C56) ||
/*for Kannada*/
- (chars[cursor] == 0x0CBF && chars[cursor + 1] == 0x0CD5) ||
- (chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CD5) ||
- (chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CD6) ||
- (chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CC2) ||
+ (chars[cursor] == 0x0CBF && chars[cursor + 1] == 0x0CD5) ||
+ (chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CD5) ||
+ (chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CD6) ||
+ (chars[cursor] == 0x0CC6 && chars[cursor + 1] == 0x0CC2) ||
(chars[cursor] == 0x0CCA && chars[cursor + 1] == 0x0CD5))
return cursor + 2;
}
} else {
saveMatra(output, matra, matraClass);
}
-
+
return TRUE;
} else
return FALSE;
output->fOutChars[output->fOutIndex + b] = output->fOutChars[output->fOutIndex + a];
output->fCharIndices[output->fOutIndex + b] = output->fCharIndices[output->fOutIndex + a];
- output->fCharTags[output->fOutIndex + b] = pstf_p;
+ output->fCharTags[output->fOutIndex + b] = pstf_p;
output->fOutChars[output->fOutIndex + a] = temp_char;
output->fCharIndices[output->fOutIndex + a] = temp_index;
gulong tags = output->fMatraTags;
if (output->fMatraWordStart)
tags &= ~init;
-
+
output->fMPreOutIndex = output->fOutIndex;
writeChar(output, output->fMpre, output->fMatraIndex, tags);
}
/* note the base consonant for post-GSUB fixups */
noteBaseConsonant(&output);
-
+
/* write base consonant */
for (i = baseConsonant; i < bcSpan; i += 1) {
writeChar(&output, chars[i], /*i*/ prev, nukt_p);
/* for the special conjuction of Cons+0x0d4d+0x0d31 or Cons+0x0d4d+0x0d30 of Malayalam */
if ((baseConsonant - 2 >= 0) &&
(chars[baseConsonant - 1] == 0x0d4d) &&
- ((chars[baseConsonant] == 0x0d31) ||
+ ((chars[baseConsonant] == 0x0d31) ||
(chars[baseConsonant] == 0x0d30)) &&
- ((chars[baseConsonant - 2] >= 0x0d15) &&
+ ((chars[baseConsonant - 2] >= 0x0d15) &&
(chars[baseConsonant - 2] <= 0x0d39))) {
swapChars (&output, -1, -3);
-
+
if (mpreFixups) {
if (mpreFixups->fFixupCount > 0) {
mpreFixups->fFixupCount--;
}
- }
- }
+ }
+ }
if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) != 0) {
gboolean is_for_0C48 = FALSE;
writeMpost(&output);
is_for_0C48 = TRUE;
- break;
+ break;
}
}
}
-
+
if (!is_for_0C48) {
writeMbelow(&output);
writeMabove(&output);
if (outMPreFixups) {
*outMPreFixups = mpreFixups;
}
-
+
return getOutputIndex(&output);
}
-/*
- * mprefixups.h: Handle left matra placement
+/*
+ * mprefixups.h: Handle left matra placement
*
* Author: Sivaraj Doddannan
* Ported from IBM's ICU engine. Original copyright:
if (baseIndex - mpreIndex > 1) {
mprefixups->fFixupData[mprefixups->fFixupCount].fBaseIndex = baseIndex;
mprefixups->fFixupData[mprefixups->fFixupCount].fMPreIndex = mpreIndex;
-
+
mprefixups->fFixupCount += 1;
}
}
/* determine post GSUB location of baseIndex and mpreIndex */
pango_ot_buffer_get_glyphs (buffer, &glyphs, &n_glyphs);
-
+
for (i = 0; i < n_glyphs; i++) {
if (baseGlyph < 0 && glyphs[i].cluster == baseIndex)
baseGlyph = i;
if (mpreGlyph < 0)
mpreGlyph = i;
mpreLimit = i + 1;
- }
+ }
}
if (baseGlyph < 0 || mpreGlyph < 0 || mpreLimit >= baseGlyph) {
continue;
for (i = 0; i < mpreCount; i += 1) {
glyphs[mpreDest + i] = mpreSave[i];
}
-
+
g_free(mpreSave);
- }
+ }
}
-/*
- * mprefixups.c: Handle left matra placement
+/*
+ * mprefixups.c: Handle left matra placement
*
* Author: Sivaraj Doddannan
* Ported from IBM's ICU engine. Original copyright:
void indic_mprefixups_free(MPreFixups *mprefixups);
void indic_mprefixups_add(MPreFixups *mprefixups, glong baseIndex, glong mpreIndex);
void indic_mprefixups_apply(MPreFixups *mprefixups, PangoOTBuffer *buffer);
-
+
G_END_DECLS
case CF_POS_AFTER :
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text);
break;
-
+
case CF_POS_BELOW :
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);
break;
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB,
tag, script_index, 0xffff, &feature_index))
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GPOS,
tag, script_index, 0xffff, &feature_index))
if (!ruleset_quark)
ruleset_quark = g_quark_from_string ("pango-syriac-ruleset");
-
+
if (!info)
return NULL;
ruleset = pango_ot_ruleset_new (info);
#define ALL_GLYPHS ~(gulong)0
-
+
if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GSUB,
syrc_tag, &script_index))
{
swap_range (PangoGlyphString *glyphs, int start, int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
glyphs->log_clusters[i] = offset;
}
-static void
+static void
fallback_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
glong n_chars = g_utf8_strlen (text, length);
const char *p;
int i;
-
+
pango_glyph_string_set_size (glyphs, n_chars);
p = text;
-
+
for (i=0; i < n_chars; i++)
{
gunichar wc;
set_glyph (font, glyphs, i, p - text, index);
}
-
+
p = g_utf8_next_char (p);
}
if (glyphs->glyphs[i].glyph)
{
PangoRectangle logical_rect;
-
+
pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
glyphs->glyphs[i].geometry.width = logical_rect.width;
}
else
glyphs->glyphs[i].geometry.width = 0;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
}
-
+
if (analysis->level % 2 != 0)
{
/* Swap all glyphs */
}
}
-static void
+static void
syriac_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
buffer = pango_ot_buffer_new (fc_font);
pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0);
pango_ot_buffer_set_zero_width_marks (buffer, TRUE);
-
+
wcs = g_utf8_to_ucs4_fast (text, length, &n_chars);
properties = g_new0 (gulong, n_chars);
-
+
syriac_assign_properties (wcs, properties, n_chars);
g_free (wcs);
-
+
p = text;
for (i=0; i < n_chars; i++)
{
{
if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK)
cluster = p - text;
-
+
pango_ot_buffer_add_glyph (buffer, index,
properties[i], cluster);
}
}
-
+
p = g_utf8_next_char (p);
}
pango_ot_ruleset_substitute (ruleset, buffer);
pango_ot_ruleset_position (ruleset, buffer);
pango_ot_buffer_output (buffer, glyphs);
-
+
g_free (properties);
pango_ot_buffer_destroy (buffer);
PANGO_ENGINE_SHAPE_DEFINE_TYPE (SyriacEngineFc, syriac_engine_fc,
syriac_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
syriac_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
*
* This file is based on the Arabic shaping code from FreeType 1 tree; original
* copyright notice:
- *
+ *
* The FreeType project -- a free and portable quality TrueType renderer.
*
* Copyright 1996-2000 by
none, none, none, none,
none, none, none, none,
none, none, none, transparent,
-
+
/* U+0710 */
right, none, dual, dual,
dual, right, right, right,
if (pos >= length)
return none;
-
+
if (string[pos] < 0x0700 ||
string[pos] >= 0x074F)
{
return causing;
else
return none;
- }
+ }
else
j = syriac[string[pos] - 0x0700];
-
+
if (!direction || j != transparent)
return j;
}
* with the Syriac rules from the Unicode-4.0 standard. The numbers
* R1...R11 below do not correspond to either the Arabic or the Syriac
* rule numbering from the Unicode standard.
- *
+ *
* Characters are here specified as appearing in the byte stream, i.e.
* *not* in visual order. Joining classes are given in angle brackets,
* glyph forms in square brackets. Glyphs affected by a specific rule are
*
* Glyphs: 0x0715 (Dalath), 0x0716 (Dalath Rish), 0x072A (Rish),
* 0x0722 (Nun), 0x071F (Kaph)
- *
+ *
*
* R1: <anything1> <transparent> <anything2>
- *
+ *
* apply joining rules for
* <anything1> <anything2> -> [shape1] [shape2]
* -> [shape1] [isolated] [shape2]
*
*
* R3: <causing|right|dual> && <!(0x0715|0x0716|0x072A)> |<alaph>|
- *
+ *
* -> [final2]
*
- * If the preceding glyph cannot be joined to the current
- * glyph and the preceding character is not a Dalath, Rish,
- * or Dotless Dalath Rish, then the Alaph takes this contextual
+ * If the preceding glyph cannot be joined to the current
+ * glyph and the preceding character is not a Dalath, Rish,
+ * or Dotless Dalath Rish, then the Alaph takes this contextual
* position.
*
* The [final2] joining rule is placed ahead of the [final] to
* give it greater precedence when choosing the correct glyph.
* If it comes after the [final] rule, the incorrect glyph is
* inserted into position.
- *
- *
+ *
+ *
* R4: <0x0715|0x0715|0x072A> |<alaph>|
*
* -> [final3]
*
- * If the previous glyph is a Dalath, Rish, or Dotless Dalath
+ * If the previous glyph is a Dalath, Rish, or Dotless Dalath
* Rish, then the Alaph takes this contextual position.
*
* The [final3] joining rule is placed ahead of the [final] to
* R5: <causing|right|dual> |<right>|
*
* -> [final]
- *
- *
+ *
+ *
* R6: <causing|right|dual> |<dual>| <!(causing|right|dual)>
*
* -> [final]
- *
- *
+ *
+ *
* R7: <causing|left|dual> |<dual>| <causing|right|dual>
*
* -> [medial]
*
* -> [medial2]
*
- * If the Alaph glyph falls in the middle of a Syriac word and
- * the preceding character cannot be joined to, then the Alaph
+ * If the Alaph glyph falls in the middle of a Syriac word and
+ * the preceding character cannot be joined to, then the Alaph
* takes this contextual position.
- *
+ *
*
* R9: |<left>| <causing|right|dual>
*
/* R2 */
if (string[i] == 0x0722 ||
- string[i] == 0x071F)
+ string[i] == 0x071F)
if (previous == causing ||
previous == right)
if (!(next == causing ||
if (string[i - 1] == 0x0715 ||
string[i - 1] == 0x0716 ||
string[i - 1] == 0x072A)
- {
+ {
properties[i] |= final3_p;
continue;
}
if (previous == causing ||
previous == right ||
previous == dual)
- if (current == right)
+ if (current == right)
{
properties[i] |= final_p;
continue;
continue;
}
- /* R11 */
+ /* R11 */
properties[i] |= isolated_p;
}
-
+
return FT_Err_Ok;
}
*
* This file is based on the Arabic shaping code from FreeType 1 tree; original
* copyright notice:
- *
+ *
* The FreeType project -- a free and portable quality TrueType renderer.
*
* Copyright 1996-2000 by
*
* The code, like the FreeType code it is derived from is dual-licensed
* under the GNU Public License and the FreeType license. See see
- * pango/opentype/FT-license.txt for full details of the FreeType
+ * pango/opentype/FT-license.txt for full details of the FreeType
* license.
*/
G_BEGIN_DECLS
-typedef enum
+typedef enum
{
isolated = 1 << 0, /* nominal */
final = 1 << 1, /* right_joining */
final3_p = isolated | final | initial | medial | medial2 | final2
} SyriacGlyphForm;
-typedef enum
+typedef enum
{
right,
left, /* not used */
/* TIS-to-Unicode glyph maps for characters 0x80-0xff
*/
static const int tis620_0[128] = {
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
0x0020, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,
0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,
};
static const int lao_0[128] = {
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
- /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
+ /**/ 0, 0, 0, 0, 0, 0, 0, 0,
0x0020, 0x0e81, 0x0e82, 0, 0x0e84, 0, 0, 0x0e87,
0x0e88, 0, 0x0e8a, 0, 0, 0x0e8d, 0, 0,
0, 0, 0, 0, 0x0e94, 0x0e95, 0x0e96, 0x0e97,
{
ThaiFontInfo *font_info;
GQuark info_id = g_quark_from_string ("thai-font-info");
-
+
font_info = g_object_get_qdata (G_OBJECT (font), info_id);
if (!font_info)
*/
font_info = g_new (ThaiFontInfo, 1);
font_info->font = font;
-
+
/* detect font set by determining availibility of OT ruleset & glyphs */
if (thai_ot_get_ruleset (font))
font_info->font_set = THAI_FONT_TIS;
font_info->font_set = THAI_FONT_TIS_MAC;
else
font_info->font_set = THAI_FONT_TIS;
-
+
g_object_set_qdata_full (G_OBJECT (font), info_id, font_info, (GDestroyNotify)g_free);
}
PANGO_ENGINE_SHAPE_DEFINE_TYPE (ThaiEngineFc, thai_engine_fc,
thai_engine_fc_class_init, NULL)
-void
+void
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
thai_engine_fc_register_type (module);
}
-void
+void
PANGO_MODULE_ENTRY(exit) (void)
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
int *n_engines)
{
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
+ * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
}
-void
+void
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, gint *n_engines)
{
*engines = script_engines;
gulong property_bit)
{
guint feature_index;
-
+
/* 0xffff == default language system */
if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB,
feature_tag, script_index, 0xffff, &feature_index))
}
-void
+void
thai_ot_shape (PangoFont *font,
PangoGlyphString *glyphs)
{
PangoOTRuleset *
thai_ot_get_ruleset (PangoFont *font);
-void
+void
thai_ot_shape (PangoFont *font,
PangoGlyphString *glyphs);
};
static void
-add_glyph (ThaiFontInfo *font_info,
- PangoGlyphString *glyphs,
- gint cluster_start,
+add_glyph (ThaiFontInfo *font_info,
+ PangoGlyphString *glyphs,
+ gint cluster_start,
PangoGlyph glyph,
gboolean combining)
{
gint index = glyphs->num_glyphs;
pango_glyph_string_set_size (glyphs, index + 1);
-
+
glyphs->glyphs[index].glyph = glyph;
glyphs->glyphs[index].attr.is_cluster_start = combining ? 0 : 1;
-
+
glyphs->log_clusters[index] = cluster_start;
pango_font_get_glyph_extents (font_info->font,
return 1;
}
break;
-
+
case 2:
if (is_char_type (cluster[0], NoTailCons|BotTailCons|SpltTailCons) &&
is_char_type (cluster[1], SaraAm))
return n;
}
break;
-
+
case 3:
if (is_char_type (cluster[0], NoTailCons|BotTailCons|SpltTailCons) &&
is_char_type (cluster[1], Tone) &&
*/
return get_adjusted_glyphs_list (font_info, cluster,
num_chrs, glyph_lists, &tis620_0_shape_table);
-
+
case THAI_FONT_TIS_MAC:
/* MacIntosh Extension
*/
return get_adjusted_glyphs_list (font_info, cluster,
num_chrs, glyph_lists, &Mac_shape_table);
-
+
case THAI_FONT_TIS_WIN:
/* Microsoft Extension
*/
const char *p;
gint n_chars = 0;
gunichar current;
-
+
for (p = text; p < text + length; p = g_utf8_next_char (p))
{
current = g_utf8_get_char (p);
return p;
}
-void
+void
thai_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
* tibetan-fc.c: Shaper for Tibetan script
*
* Copyright (C) 2005 DIT, Government of Bhutan <http://www.dit.gov.bt>
- * Contact person : Pema Geyleg <pema_geyleg@druknet.bt>
+ * Contact person : Pema Geyleg <pema_geyleg@druknet.bt>
*
- * Based on code from khmer shapers developed by Jens Herden
+ * Based on code from khmer shapers developed by Jens Herden
* <jens@tibetanos.inf > and Javier Sola <javier@tibetanos.info>
*
* Based on code from other shapers
* Copyright (C) 2001, 2002 IBM Corporation
* Author: Eric Mader <mader@jtcsv.com>
*
- * The first module for Tibetan shaper was developed by Mr. Karunakar under
- * PanLocalization project.
+ * The first module for Tibetan shaper was developed by Mr. Karunakar under
+ * PanLocalization project.
* Mr. Chris Fynn, Mr.Javier Sola, Mr. Namgay Thinley were involved
* while developing this shaper.
*
-// Vocabulary
-// Base -> A consonant in its full (not subscript) form. It is the
+// Vocabulary
+// Base -> A consonant in its full (not subscript) form. It is the
// center of the syllable, it can be souranded by subjoined consonants, vowels,
// signs... but there is only one base in a stack, it has to be coded as
-// the first character of the syllable.Included here are also groups of base + subjoined
-// which are represented by one single code point in unicode (e.g. 0F43) Also other characters that might take
-// subjoined consonants or other combining characters.
-// Subjoined -> Subjoined consonants and groups of subjoined consonants which have a single code-point
+// the first character of the syllable.Included here are also groups of base + subjoined
+// which are represented by one single code point in unicode (e.g. 0F43) Also other characters that might take
+// subjoined consonants or other combining characters.
+// Subjoined -> Subjoined consonants and groups of subjoined consonants which have a single code-point
// to repersent the group (even if each subjoined consonant is represented independently
// by anothe code-point
-// Tsa Phru --> Tsa Phru character, Bhutanese people will always place it right after the base, but sometimes, due to
-// "normalization"
+// Tsa Phru --> Tsa Phru character, Bhutanese people will always place it right after the base, but sometimes, due to
+// "normalization"
// is placed after all the subjoined consonants, and it is also permitted there.
// A Chung Vowel lengthening mark --> . 0F71 It is placed after the base and any subjoined consonants but before any vowels
// Precomposed Sanskrit vowels --> The are combinations of subjoined consonants + vowels that have been assigned
// They are avoided, and users are encouraged to use the combination of code-points that
// represents the same sound instead of using this combined characters. This is included here
// for compatibility with possible texts that use them (they are not in the Dzongkha keyboard).
-// Halanta -> The Halanta or Virama character 0F84 indicates that a consonant should not use its inheernt vowel,
+// Halanta -> The Halanta or Virama character 0F84 indicates that a consonant should not use its inheernt vowel,
// in spite of not having other vowels present. It is usually placed immediatly after a base consonant,
// but in some special cases it can also be placed after a subjoined consonant, so this is also
// permitted in this algorithm. (Halanta is always displayed in Tibetan not used as a connecting char)
//
// Subjoined vowels -> Dependent vowels (matras) placed below the base and below all subjoined consonants. There
-// might be as much as three subjoined vowels in a given stack (only one in general text, but up
+// might be as much as three subjoined vowels in a given stack (only one in general text, but up
// to three for abreviations, they have to be permitted).
// Superscript vowels -> There are three superscript vowels, and they can be repeated or combined (up to three
// times. They can combine with subjoined vowels, and are always coded after these.
// Digits -> Digits are not considered as non-combining characters because there are a few characters which
// combine with them, so they have to be considered independently.
// Digit combining marks -> dependent marks that combine with digits.
-//
+//
// TODO
// There are a number of characters in the CJK block that are used in Tibetan script, two of these are symbols
// are used as bases for combining glyphs, and have not been encoded in Tibetan. As these characters are outside
// of the tibetan block, they have not been treated in this program.
-
+
enum TibetanCharClassValues
{
CC_RESERVED = 0, //Non Combining Characters
CC_BASE = 1, // Base Consonants, Base Consonants with Subjoined attached in code point, Sanskrit base marks
CC_SUBJOINED = 2, // Subjoined Consonats, combination of more than Subjoined Consonants in the code point
- CC_TSA_PHRU = 3, // Tsa-Phru character 0F39
+ CC_TSA_PHRU = 3, // Tsa-Phru character 0F39
CC_A_CHUNG = 4, // Vowel Lenthening a-chung mark 0F71
CC_COMP_SANSKRIT = 5, // Precomposed Sanskrit vowels including Subjoined characters and vowels
CC_HALANTA = 6, // Halanta Character 0F84
// simple classes, they are used in the statetable (in this file) to control the length of a syllable
// they are also used to know where a character should be placed (location in reference to the base character)
// and also to know if a character, when independtly displayed, should be displayed with a dotted-circle to
- // indicate error in syllable construction
- _xx = CC_RESERVED,
- _ba = CC_BASE,
- _sj = CC_SUBJOINED | CF_DOTTED_CIRCLE | CF_POS_BELOW,
- _tp = CC_TSA_PHRU | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
- _ac = CC_A_CHUNG | CF_DOTTED_CIRCLE | CF_POS_BELOW,
- _cs = CC_COMP_SANSKRIT | CF_DOTTED_CIRCLE | CF_POS_BELOW,
- _ha = CC_HALANTA | CF_DOTTED_CIRCLE | CF_POS_BELOW,
- _bv = CC_BELOW_VOWEL | CF_DOTTED_CIRCLE | CF_POS_BELOW,
- _av = CC_ABOVE_VOWEL | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
- _an = CC_ANUSVARA | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
- _cb = CC_CANDRABINDU | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
- _vs = CC_VISARGA | CF_DOTTED_CIRCLE| CF_POS_AFTER,
- _as = CC_ABOVE_S_MARK | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
- _bs = CC_BELOW_S_MARK | CF_DOTTED_CIRCLE | CF_POS_BELOW,
- _di = CC_DIGIT | CF_DIGIT,
- _pd = CC_PRE_DIGIT_MARK | CF_DOTTED_CIRCLE | CF_PREDIGIT | CF_POS_BEFORE ,
- _bd = CC_POST_BELOW_DIGIT_M | CF_DOTTED_CIRCLE | CF_POS_AFTER
+ // indicate error in syllable construction
+ _xx = CC_RESERVED,
+ _ba = CC_BASE,
+ _sj = CC_SUBJOINED | CF_DOTTED_CIRCLE | CF_POS_BELOW,
+ _tp = CC_TSA_PHRU | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
+ _ac = CC_A_CHUNG | CF_DOTTED_CIRCLE | CF_POS_BELOW,
+ _cs = CC_COMP_SANSKRIT | CF_DOTTED_CIRCLE | CF_POS_BELOW,
+ _ha = CC_HALANTA | CF_DOTTED_CIRCLE | CF_POS_BELOW,
+ _bv = CC_BELOW_VOWEL | CF_DOTTED_CIRCLE | CF_POS_BELOW,
+ _av = CC_ABOVE_VOWEL | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
+ _an = CC_ANUSVARA | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
+ _cb = CC_CANDRABINDU | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
+ _vs = CC_VISARGA | CF_DOTTED_CIRCLE| CF_POS_AFTER,
+ _as = CC_ABOVE_S_MARK | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
+ _bs = CC_BELOW_S_MARK | CF_DOTTED_CIRCLE | CF_POS_BELOW,
+ _di = CC_DIGIT | CF_DIGIT,
+ _pd = CC_PRE_DIGIT_MARK | CF_DOTTED_CIRCLE | CF_PREDIGIT | CF_POS_BEFORE ,
+ _bd = CC_POST_BELOW_DIGIT_M | CF_DOTTED_CIRCLE | CF_POS_AFTER
};
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
_xx, _ba, _xx, _xx, _ba, _ba, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0F00 - 0F0F 0
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _bd, _bd, _xx, _xx, _xx, _xx, _xx, _xx, // 0F10 - 0F1F 1
- _di, _di, _di, _di, _di, _di, _di, _di, _di, _di, _xx, _xx, _xx, _xx, _xx, _xx, // 0F20 - 0F2F 2
- _xx, _xx, _xx, _xx, _xx, _bs, _xx, _bs, _xx, _tp, _xx, _xx, _xx, _xx, _bd, _pd, // 0F30 - 0F3F 3
+ _di, _di, _di, _di, _di, _di, _di, _di, _di, _di, _xx, _xx, _xx, _xx, _xx, _xx, // 0F20 - 0F2F 2
+ _xx, _xx, _xx, _xx, _xx, _bs, _xx, _bs, _xx, _tp, _xx, _xx, _xx, _xx, _bd, _pd, // 0F30 - 0F3F 3
_ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _ba, _ba, _ba, _ba, _ba, _ba, _ba, // 0F40 - 0F4F 4
_ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, // 0F50 - 0F5F 5
_ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, _xx, // 0F60 - 0F6F 6
_xx, _xx, _xx, _xx, _xx, _xx, _bs, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FC0 - 0FCF c
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx,// 0FD0 - 0FDF d
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FE0 - 0FEF e
- _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FF0 - 0FFF f
+ _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FF0 - 0FFF f
};
/* this define must reflect the range of tibetanCharClasses */
//xx ba sj tp ac cs ha bv av an cb vs as bs di pd bd
{ 1, 2, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, 20, 21, 21,}, // 0 - ground state
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 1 - exit state (or sign to the right of the syllable)
- {-1, -1, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 2 - Base consonant
+ {-1, -1, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 2 - Base consonant
{-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 3 - Tsa phru after base
- {-1, -1, 4, 6, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 4 - Subjoined consonant after base
+ {-1, -1, 4, 6, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 4 - Subjoined consonant after base
{-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 5 - Subjoined consonant after tsa phru
{-1, -1, -1, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 6 - Tsa phru after subjoined consonant
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 7 - Pre Composed Sanskrit
{-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, -1, 19, 19, -1, -1, -1,}, // 9 - Halanta
{-1, -1, -1, -1, -1, -1, -1, 11, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 10 - below vowel 1
{-1, -1, -1, -1, -1, -1, -1, 12, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 11 - below vowel 2
- {-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 12 - below vowel 3
+ {-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 12 - below vowel 3
{-1, -1, -1, -1, -1, -1, -1, -1, 14, 17, 17, 18, 19, 19, -1, -1, -1,}, // 13 - Anusvara before vowel
{-1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 17, 18, 19, 19, -1, -1, -1,}, // 14 - above vowel 1
{-1, -1, -1, -1, -1, -1, -1, -1, 16, 17, 17, 18, 19, 19, -1, -1, -1,}, // 15 - above vowel 2
{-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 17, 18, 19, 19, -1, -1, -1,}, // 16 - above vowel 3
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 19, -1, -1, -1,}, // 17 - Anusvara or Candrabindu after vowel
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 18 - Visarga
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 19, -1, -1, -1,}, // 17 - Anusvara or Candrabindu after vowel
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 18 - Visarga
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 19 - strss mark
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 21,}, // 20 - digit
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 21,}, // 20 - digit
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 21 - digit mark
};
}
/* If it encounters a digit followed by number pre combining mark, then reorder the two characters
- * coeng Ro if they are present
+ * coeng Ro if they are present
*/
for (i = cursor; i < syllable; i += 1)
{
charClass = get_char_class (wcs[i]);
- if ((charClass & CF_DIGIT )
+ if ((charClass & CF_DIGIT )
&& ( get_char_class (wcs[i+1]) & CF_PREDIGIT))
{
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_PRE_NUMBER_MARK), pref_p, p - text);
p = g_utf8_next_char (p);
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pref_p, p - text);
- i += 1;
+ i += 1;
} else {
switch (charClass & CF_POS_MASK)
{
case CF_POS_AFTER :
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text);
break;
-
+
case CF_POS_BELOW :
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);
break;
pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), default_p, p - text);
break;
} /* switch */
- }
-
+ }
+
p = g_utf8_next_char (p);
} /* for */
int run;
int width, height;
gpointer surface;
-
+
g_type_init();
setlocale (LC_ALL, "");
parse_options (argc, argv);
-
+
view = opt_viewer;
g_assert (view->id);
GError *error;
convert_argv[2] = opt_output;
-
+
if (!g_spawn_async_with_pipes (NULL, (gchar **)convert_argv, NULL,
G_SPAWN_SEARCH_PATH |
G_SPAWN_STDOUT_TO_DEV_NULL |
if (!view->write)
fail ("%s viewer backend does not support displaying or writing", view->name);
display_argv[2] = title;
-
+
if (!g_spawn_async_with_pipes (NULL, (gchar **)display_argv, NULL,
G_SPAWN_DO_NOT_REAP_CHILD |
G_SPAWN_SEARCH_PATH |
return instance;
}
-static void
+static void
pangocairo_view_destroy (gpointer instance)
{
CairoViewer *c = (CairoViewer *) instance;
return context;
}
-typedef struct
+typedef struct
{
gpointer backend;
return surface;
}
-static void
+static void
pangocairo_view_destroy_surface (gpointer instance,
gpointer surface)
{
PangoRectangle ink, logical;
double lw = cairo_get_line_width (cr);
PangoLayoutIter* iter;
-
+
pango_layout_get_extents (layout, &ink, &logical);
/* draw resolved gravity "roof" in blue */
cairo_set_source_rgba (cr, 0.0, 0.0, 0.7, 0.2);
cairo_stroke (cr);
cairo_restore (cr);
-
+
/* draw block progression arrow in green */
cairo_save (cr);
cairo_set_source_rgba (cr, 0.0, 0.7, 0.0, 0.2);
cairo_stroke (cr);
cairo_restore (cr);
-
+
/* draw baselines with line direction arrow in orange */
cairo_save (cr);
cairo_set_source_rgba (cr, 1.0, 0.5, 0.0, 0.5);
}
cairo_set_matrix (cr, &cairo_matrix);
-
+
pango_cairo_update_context (cr, context);
}
-static void
+static void
pangocairo_view_render (gpointer instance,
gpointer surface,
PangoContext *context,
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_paint (cr);
-
+
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
do_output (context, render_callback, transform_callback, cr, state, NULL, NULL);
{
FcPatternDel (pattern, FC_HINTING);
FcPatternAddBool (pattern, FC_HINTING, opt_hinting != HINT_NONE);
-
+
FcPatternDel (pattern, FC_AUTOHINT);
FcPatternAddBool (pattern, FC_AUTOHINT, opt_hinting == HINT_AUTO);
}
return fontmap;
}
-static void
+static void
pangoft2_view_destroy (gpointer instance)
{
g_object_unref (instance);
return bitmap;
}
-static void
+static void
pangoft2_view_destroy_surface (gpointer instance,
gpointer surface)
{
x, y);
}
-static void
+static void
pangoft2_view_render (gpointer instance,
gpointer surface,
PangoContext *context,
#include <pango/pangox.h>
-static void
+static void
pangox_view_destroy (gpointer instance)
{
XViewer *x = (XViewer *)instance;
return context;
}
-typedef struct
+typedef struct
{
XViewer *x;
Drawable drawable;
x, y);
}
-static void
+static void
pangox_view_render (gpointer instance,
gpointer surface,
PangoContext *context,
{
FcPatternDel (pattern, FC_HINTING);
FcPatternAddBool (pattern, FC_HINTING, opt_hinting != HINT_NONE);
-
+
FcPatternDel (pattern, FC_AUTOHINT);
FcPatternAddBool (pattern, FC_AUTOHINT, opt_hinting == HINT_AUTO);
}
return instance;
}
-static void
+static void
pangoxft_view_destroy (gpointer instance)
{
XViewer *x = (XViewer *)instance;
return pango_xft_get_context (x->display, x->screen);
}
-typedef struct
+typedef struct
{
XftDraw *draw;
XftColor color;
x * PANGO_SCALE, y * PANGO_SCALE);
}
-static void
+static void
pangoxft_view_render (gpointer instance,
gpointer surface,
PangoContext *context,
PangoRectangle logical_rect;
int size, start_size, end_size, increment;
int x = 0, y = 0;
-
+
if (!supports_matrix)
{
const PangoMatrix* matrix;
if (!ret && error)
{
g_set_error(error,
- G_OPTION_ERROR,
+ G_OPTION_ERROR,
G_OPTION_ERROR_BAD_VALUE,
"Argument for %s must be one of %s",
name,
else
{
g_set_error(error,
- G_OPTION_ERROR,
+ G_OPTION_ERROR,
G_OPTION_ERROR_BAD_VALUE,
"Argument for --hinting must be one of none/auto/full");
ret = FALSE;
}
-
+
return ret;
}
{
GString *backends = g_string_new (NULL);
const PangoViewer **viewer;
-
+
for (viewer = viewers; *viewer; viewer++)
if ((*viewer)->id)
{
g_string_append_c (backends, '/');
}
g_string_truncate (backends, MAX (0, (gint)backends->len - 1));
-
+
return g_string_free(backends,FALSE);
}
for (viewer = viewers; *viewer; viewer++)
if ((*viewer)->id)
i++;
-
+
return i;
}
{
GString *description = g_string_new("Pango backend to use for rendering ");
int backends_count = backends_get_count ();
-
+
if (backends_count > 1)
g_string_append_printf(description,"(default: %s)", (*viewers)->id);
else if (backends_count == 1)
g_string_append_printf(description,"(no backends found!)");
return g_string_free(description,FALSE);
-
+
}
gchar *backends = backends_to_string ();
g_set_error(error,
- G_OPTION_ERROR,
+ G_OPTION_ERROR,
G_OPTION_ERROR_BAD_VALUE,
- "Available --backend options are: %s",
+ "Available --backend options are: %s",
backends);
g_free(backends);
ret = FALSE;
{
if (opt_text && argc != 1)
fail ("When specifying --text, no file should be given");
-
+
g_printerr ("Usage: %s [OPTION...] FILE\n", prog_name);
exit (1);
}
gunichar wc;
GList *result = NULL;
char *last_para = text;
-
+
while (*p)
{
wc = g_utf8_get_char (p);
para->height = 0;
last_para = next;
-
+
result = g_list_prepend (result, para);
}
if (!wc) /* incomplete character at end */
while (para_list && height < y)
{
Paragraph *para = para_list->data;
-
+
if (height + para->height >= y)
{
gboolean result = pango_layout_xy_to_index (para->layout,
x * PANGO_SCALE,
- (y - height) * PANGO_SCALE,
+ (y - height) * PANGO_SCALE,
index, NULL);
if (result && para_return)
*para_return = para;
return result;
}
-
+
height += para->height;
para_list = para_list->next;
}
/* Given a paragraph and offset in that paragraph, find the
* bounding rectangle for the character at the offset.
- */
+ */
void
char_bounds (Paragraph *para, int index, int width, PangoRectangle *rect)
{
GList *para_list;
-
+
int height = 0;
-
+
para_list = paragraphs;
while (para_list)
{
Paragraph *cur_para = para_list->data;
-
+
if (cur_para == para)
{
PangoRectangle pos;
rect->y = height + PANGO_PIXELS (pos.y);
rect->height = PANGO_PIXELS (pos.height);
}
-
+
height += cur_para->height;
para_list = para_list->next;
}
{
Paragraph *para = tmp_list->data;
PangoRectangle logical_rect;
-
+
tmp_list = tmp_list->next;
pango_layout_set_alignment (para->layout,
pango_layout_get_extents (para->layout, NULL, &logical_rect);
para->height = PANGO_PIXELS (logical_rect.height);
-
+
height += para->height;
}
guint height = 0;
HDC hdc;
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND|GDK_GC_FONT;
-
+
gdk_draw_rectangle (GTK_LAYOUT (layout)->bin_window,
layout->style->base_gc[layout->state],
TRUE,
- area->x, area->y,
+ area->x, area->y,
area->width, area->height);
-
+
gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], area);
hdc = gdk_win32_hdc_get (GTK_LAYOUT (layout)->bin_window,
{
Paragraph *para = tmp_list->data;
tmp_list = tmp_list->next;
-
+
if (height + para->height >= GTK_LAYOUT (layout)->yoffset + area->y)
pango_win32_render_layout (hdc, para->layout,
0, height - GTK_LAYOUT (layout)->yoffset);
Paragraph *para = NULL;
int offset;
gchar *message;
-
+
xy_to_cp (layout->allocation.width,
event->x, event->y + GTK_LAYOUT (layout)->yoffset,
¶, &offset);
highlight_para = para;
highlight_offset = offset;
-
+
if (para)
{
gunichar wc;
wc = g_utf8_get_char (para->text + offset);
message = g_strdup_printf ("Current char: U%04x", wc);
-
+
xor_char (layout, NULL, highlight_para, highlight_offset);
}
else
checkbutton_toggled (GtkWidget *widget, gpointer data)
{
GList *para_list;
-
+
pango_context_set_base_dir (context, GTK_TOGGLE_BUTTON (widget)->active ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
para_list = paragraphs;
{
char *str = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
PangoFontDescription *tmp_desc;
-
+
tmp_desc = pango_font_description_from_string (str);
pango_font_description_set_style(font_description, pango_font_description_get_style(tmp_desc));
pango_font_description_free (tmp_desc);
g_free (str);
-
+
reload_font ();
}
if (pango_font_description_get_style(a) != pango_font_description_get_style(b))
return pango_font_description_get_style(a) - pango_font_description_get_style(b);
-
+
if (pango_font_description_get_stretch(a) != pango_font_description_get_stretch(b))
return pango_font_description_get_stretch(a) - pango_font_description_get_stretch(b);
return compare_font_descriptions (*(PangoFontDescription **)a, *(PangoFontDescription **)b);
}
-typedef struct
+typedef struct
{
PangoFontDescription **descs;
int n_descs;
int n_families;
const char *family_name = pango_font_description_get_family(font_description);
- /*
+ /*
* Now map back the given family name to the family. There are more efficient
* ways to handle this but it should not matter much ...
*/
for (i=0; i<info->n_descs; i++)
{
char *str;
-
+
PangoFontDescription *tmp_desc;
tmp_desc = info->descs[i];
pango_font_description_set_family(tmp_desc, NULL);
pango_font_description_unset_fields(tmp_desc, PANGO_FONT_MASK_SIZE);
-
+
str = pango_font_description_to_string (tmp_desc);
style_list = g_list_prepend (style_list, str);
}
styles_combo = combo;
fill_styles_combo (combo);
-
+
return combo;
}
PangoFontFamily **families;
GList *family_list = NULL;
int i;
-
+
pango_context_list_families (context, &families, &n_families);
qsort (families, n_families, sizeof(char *), cmp_families);
family_list = g_list_prepend (family_list, pango_font_family_get_name (families[i]));
family_list = g_list_reverse (family_list);
-
+
combo = gtk_combo_new ();
gtk_combo_set_popdown_strings (GTK_COMBO (combo), family_list);
gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
GTK_SIGNAL_FUNC (set_family), NULL);
-
+
g_list_free (family_list);
return combo;
GtkWidget *option_menu;
GtkWidget *spin_button;
GtkAdjustment *adj;
-
+
hbox = gtk_hbox_new (FALSE, 4);
-
+
util_hbox = gtk_hbox_new (FALSE, 2);
label = gtk_label_new ("Family:");
gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0);
option_menu = make_families_menu ();
gtk_box_pack_start (GTK_BOX (util_hbox), option_menu, FALSE, FALSE, 0);
-
+
gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0);
util_hbox = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0);
option_menu = make_styles_combo ();
gtk_box_pack_start (GTK_BOX (util_hbox), option_menu, FALSE, FALSE, 0);
-
+
gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0);
util_hbox = gtk_hbox_new (FALSE, 2);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (font_size_changed), NULL);
-
+
return hbox;
}
-int
+int
main (int argc, char **argv)
{
char *text;
GtkWidget *checkbutton;
gtk_init (&argc, &argv);
-
+
if (argc != 2)
{
fprintf (stderr, "Usage: %s FILE\n", g_get_prgname ());
hbox = make_font_selector ();
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
+
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-
+
gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0);
-
+
layout = gtk_layout_new (NULL, NULL);
gtk_widget_set_events (layout, GDK_BUTTON_PRESS_MASK);
gtk_widget_set_app_paintable (layout, TRUE);
gtk_widget_show_all (window);
gtk_main ();
-
+
return 0;
}
return instance;
}
-void
+void
x_view_destroy (gpointer instance)
{
XViewer *x = (XViewer *)instance;
return (gpointer) pixmap;
}
-void
+void
x_view_destroy_surface (gpointer instance,
gpointer surface)
{
extents.x, extents.y);
XFreeGC (display, gc);
-
+
XDestroyRegion (*update_region);
*update_region = NULL;
}
bg, bg);
XSelectInput (x->display, window, ExposureMask | KeyPressMask);
-
+
XMapWindow (x->display, window);
XmbSetWMProperties (x->display, window,
title,
NULL, NULL, 0, NULL, NULL, NULL);
-
+
memset ((char *)&size_hints, 0, sizeof (XSizeHints));
size_hints.flags = PSize | PMaxSize;
size_hints.width = width; size_hints.height = height; /* for compat only */
size_hints.max_width = width; size_hints.max_height = height;
-
+
XSetWMNormalHints (x->display, window, &size_hints);
return (gpointer) window;
{
if (!XPending (x->display) && update_region)
update (x->display, pixmap, window, &update_region);
-
+
XNextEvent (x->display, &xev);
switch (xev.xany.type) {
case KeyPress:
#include "viewer.h"
-typedef struct
+typedef struct
{
Display *display;
int screen;
#define PARAGRAPH_SEPARATOR 0x2029
#define PARAGRAPH_SEPARATOR_STRING "\xE2\x80\xA9"
-
+
/* See http://www.unicode.org/unicode/reports/tr14/ if you hope
* to understand the line breaking code.
*/
g_return_if_fail (attrs != NULL);
next = text;
-
+
prev_type = (GUnicodeType) -1;
prev_break_type = G_UNICODE_BREAK_UNKNOWN;
prev_was_break_space = FALSE;
}
else
next_wc = g_utf8_get_char (next);
-
+
next_break_type = g_unichar_break_type (next_wc);
next_break_type = BREAK_TYPE_SAFE (next_break_type);
}
{
JamoType prev_end = HangulJamoProps[prev_jamo].end ;
JamoType this_start = HangulJamoProps[ jamo].start;
-
+
/* See comments before IS_JAMO */
makes_hangul_syllable = (prev_end == this_start) || (prev_end + 1 == this_start);
}
break;
}
}
-
+
/* If this is a grapheme boundary, we have to decide if backspace
* deletes a character or the whole grapheme cluster */
if (attrs[i].is_cursor_position)
attrs[i].is_line_break = FALSE;
attrs[i].is_mandatory_break = FALSE;
-
+
if (attrs[i].is_cursor_position) /* If it's not a grapheme boundary,
* it's not a line break either
*/
if (break_type == G_UNICODE_BREAK_SPACE &&
next_break_type == G_UNICODE_BREAK_COMBINING_MARK)
break_type = G_UNICODE_BREAK_IDEOGRAPHIC;
-
+
/* Unicode doesn't specify char wrap; we wrap around all chars
* except where a line break is prohibited, which means we
* effectively break everywhere except inside runs of spaces.
*/
- attrs[i].is_char_break = TRUE;
-
+ attrs[i].is_char_break = TRUE;
+
/* Make any necessary replacements first */
switch (prev_break_type)
{
switch (break_op)
{
case BREAK_PROHIBITED:
- /* can't break here */
+ /* can't break here */
attrs[i].is_char_break = FALSE;
break;
case BREAK_IF_SPACES:
/* break if prev char was space */
- if (prev_was_break_space)
+ if (prev_was_break_space)
attrs[i].is_line_break = TRUE;
break;
}
}
}
-
+
if (break_type != G_UNICODE_BREAK_SPACE)
{
prev_break_type = break_type;
}
/* ---- Sentence breaks ---- */
-
+
/* The Unicode spec specifies sentence breakpoints, so that a piece of
* text would be partitioned into sentences, and all characters would
* be inside some sentence. This code implements that for is_sentence_boundary,
attrs[i].is_sentence_start = TRUE; \
break; \
}
-
+
/* No sentence break at the start of the text */
/* default to not a sentence breakpoint */
attrs[i].is_sentence_boundary = FALSE;
attrs[i].is_sentence_start = FALSE;
attrs[i].is_sentence_end = FALSE;
-
+
/* FIXME the Unicode spec lumps control/format chars with
* line/para separators in descriptive text, but not in the
* character class specs, in table 5-6, so who knows whether you
possible_sentence_boundary = -1;
MAYBE_START_NEW_SENTENCE;
-
+
break;
}
break;
/* wc might not be a valid Unicode base character, but really all we
* need to know is the last non-combining character */
- if (type != G_UNICODE_COMBINING_MARK &&
- type != G_UNICODE_ENCLOSING_MARK &&
+ if (type != G_UNICODE_COMBINING_MARK &&
+ type != G_UNICODE_ENCLOSING_MARK &&
type != G_UNICODE_NON_SPACING_MARK)
base_character = wc;
}
{
g_return_if_fail (analysis != NULL);
g_return_if_fail (attrs != NULL);
-
+
pango_default_break (text, length, analysis, attrs, attrs_len);
tailor_break (text, length, analysis, attrs, attrs_len);
}
* @length: length of @text in bytes, or -1 if nul-terminated
* @paragraph_delimiter_index: return location for index of delimiter
* @next_paragraph_start: return location for start of next paragraph
- *
+ *
* Locates a paragraph boundary in @text. A boundary is caused by
* delimiter characters, such as a newline, carriage return, carriage
* return-newline pair, or Unicode paragraph separator character. The
break;
}
}
-
+
if (*p == '\n' ||
*p == '\r' ||
!strncmp(p, PARAGRAPH_SEPARATOR_STRING,
}
else
prev_sep = 0;
-
+
p = g_utf8_next_char (p);
}
chars_broken += tailor_segment (range_start, range_end, range_engine, chars_broken, &analysis, log_attrs);
if (chars_broken + 1 < attrs_len)
- g_warning ("pango_get_log_attrs: attrs_len should have been at least %d, but was %d. Expect corrupted memory.",
+ g_warning ("pango_get_log_attrs: attrs_len should have been at least %d, but was %d. Expect corrupted memory.",
chars_broken + 1,
attrs_len);
}
* gap center position until:
*
* line_width - gap_width + ellipsize_width <= goal_width
- *
+ *
* Line: [-------------------------------------------]
* Runs: [------)[---------------)[------------------]
* Gap center: *
{
PangoLayout *layout; /* Layout being ellipsized */
PangoAttrList *attrs; /* Attributes used for itemization/shaping */
-
+
RunInfo *run_info; /* Array of information about each run */
int n_runs;
int total_width; /* Original width of line in Pango units */
int gap_center; /* Goal for center of gap */
-
+
PangoGlyphItem *ellipsis_run; /* Run created to hold ellipsis */
int ellipsis_width; /* Width of ellipsis, in Pango units */
int ellipsis_is_cjk; /* Whether the first character in the ellipsized
* is wide; this triggers us to try to use a
* mid-line ellipsis instead of a baseline
*/
-
+
PangoAttrIterator *line_start_attr; /* Cached PangoAttrIterator for the start of the run */
-
+
LineIter gap_start_iter; /* Iteratator pointig to the first cluster in gap */
int gap_start_x; /* x position of start of gap, in Pango units */
PangoAttrIterator *gap_start_attr; /* Attribute iterator pointing to a range containing
* the first character in gap */
-
+
LineIter gap_end_iter; /* Iterator pointing to last cluster in gap */
int gap_end_x; /* x position of end of gap, in Pango units */
};
state->layout = line->layout;
state->attrs = attrs;
-
+
state->n_runs = g_slist_length (line->runs);
state->run_info = g_new (RunInfo, state->n_runs);
PangoGlyphString *glyphs = run_iter->glyph_item->glyphs;
int width = 0;
int i;
-
+
if (run_iter->start_glyph < run_iter->end_glyph) /* LTR */
{
for (i = run_iter->start_glyph; i < run_iter->end_glyph; i++)
if (iter->run_iter.end_char == run_info->run->item->num_chars && iter->run_index == state->n_runs - 1)
return TRUE;
-
+
return state->layout->log_attrs[run_info->start_offset + iter->run_iter.end_char + 1].is_cursor_position;
}
pango_item_free (state->ellipsis_run->item);
state->ellipsis_run->item = NULL;
}
-
+
/* Create an attribute list
*/
run_attrs = pango_attr_iterator_get_attrs (state->gap_start_attr);
item->analysis.language, g_utf8_get_char (ellipsis_text)))
{
pango_item_free (item);
-
+
/* Modify the fallback iter while it is inside the PangoAttrList; Don't try this at home
*/
- ((PangoAttrInt *)fallback)->value = TRUE;
+ ((PangoAttrInt *)fallback)->value = TRUE;
ellipsis_text = "...";
item = itemize_text (state, ellipsis_text, attrs);
}
-
+
pango_attr_list_unref (attrs);
-
+
state->ellipsis_run->item = item;
/* Now shape
int new_index)
{
int start, end;
-
+
do
{
pango_attr_iterator_range (iter, &start, &end);
/* See if the current attribute range contains the new start position
*/
int start, end;
-
+
pango_attr_iterator_range (state->gap_start_attr, &start, &end);
if (state->gap_start_iter.run_iter.start_index < start)
state->gap_start_attr = pango_attr_iterator_copy (state->line_start_attr);
advance_iterator_to (state->gap_start_attr,
state->run_info[state->gap_start_iter.run_index].run->item->offset);
-
+
recompute = TRUE;
}
int i;
int x;
int cluster_width;
-
+
switch (state->layout->ellipsize)
{
case PANGO_ELLIPSIZE_NONE:
i--;
x -= state->run_info[i].width;
}
-
+
/* Find the cluster containing the gap center
*/
state->gap_start_iter.run_index = i;
state->gap_end_x = x + cluster_width;
/* Expand the gap to a full span
- */
+ */
while (!starts_at_ellipsization_boundary (state, &state->gap_start_iter))
{
line_iter_prev_cluster (state, &state->gap_start_iter);
if (state->gap_end_x == new_gap_end_x && state->gap_start_x == new_gap_start_x)
return FALSE;
-
+
/* In the case where we could remove a span from either end of the
* gap, we look at which causes the smaller increase in the
* MAX (gap_end - gap_center, gap_start - gap_center)
{
state->gap_start_iter = new_gap_start_iter;
state->gap_start_x = new_gap_start_x;
-
+
update_ellipsis_shape (state);
}
else
* _pango_layout_line_ellipsize:
* @line: a #PangoLayoutLine
* @attrs: Attributes being used for itemization/shaping
- *
+ *
* Given a #PangoLayoutLine with the runs still in logical order, ellipsize
* it according the layout's policy to fit within the set width of the layout.
*
}
fixup_ellipsis_run (&state);
-
+
g_slist_free (line->runs);
line->runs = get_run_list (&state);
is_ellipsized = TRUE;
guint16 mask;
guint static_family : 1;
guint size_is_absolute : 1;
-
+
int size;
};
pango_font_description_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoFontDescription"),
(GBoxedCopyFunc)pango_font_description_copy,
/**
* pango_font_description_new:
- *
+ *
* Creates a new font description structure with all fields unset.
- *
+ *
* Return value: the newly allocated #PangoFontDescription, which
* should be freed using pango_font_description_free().
**/
* pango_font_description_set_family:
* @desc: a #PangoFontDescription.
* @family: a string representing the family name.
- *
+ *
* Sets the family name field of a font description. The family
* name represents a family of related font styles, and will
* resolve to a particular #PangoFontFamily. In some uses of
* pango_font_description_set_family_static:
* @desc: a #PangoFontDescription
* @family: a string representing the family name.
- *
+ *
* Like pango_font_description_set_family(), except that no
* copy of @family is made. The caller must make sure that the
* string passed in stays around until @desc has been freed
if (desc->family_name == family)
return;
-
+
if (desc->family_name && !desc->static_family)
g_free (desc->family_name);
/**
* pango_font_description_get_family:
* @desc: a #PangoFontDescription.
- *
+ *
* Gets the family name field of a font description. See
* pango_font_description_set_family().
- *
+ *
* Return value: the family name field for the font description, or
* %NULL if not previously set. This has the same life-time
* as the font description itself and should not be freed.
* pango_font_description_set_style:
* @desc: a #PangoFontDescription
* @style: the style for the font description
- *
+ *
* Sets the style field of a #PangoFontDescription. The
* #PangoStyle enumeration describes whether the font is slanted and
* the manner in which it is slanted; it can be either
* #PANGO_STYLE_NORMAL, #PANGO_STYLE_ITALIC, or #PANGO_STYLE_OBLIQUE.
* Most fonts will either have a italic style or an oblique
- * style, but not both, and font matching in Pango will
+ * style, but not both, and font matching in Pango will
* match italic specifications with oblique fonts and vice-versa
* if an exact match is not found.
**/
/**
* pango_font_description_get_style:
* @desc: a #PangoFontDescription
- *
+ *
* Gets the style field of a #PangoFontDescription. See
* pango_font_description_set_style().
- *
- * Return value: the style field for the font description.
+ *
+ * Return value: the style field for the font description.
* Use pango_font_description_get_set_fields() to find out if
* the field was explicitly set or not.
**/
* pango_font_description_set_variant:
* @desc: a #PangoFontDescription
* @variant: the variant type for the font description.
- *
+ *
* Sets the variant field of a font description. The #PangoVariant
* can either be %PANGO_VARIANT_NORMAL or %PANGO_VARIANT_SMALL_CAPS.
**/
PangoVariant variant)
{
g_return_if_fail (desc != NULL);
-
+
desc->variant = variant;
desc->mask |= PANGO_FONT_MASK_VARIANT;
}
/**
* pango_font_description_get_variant:
* @desc: a #PangoFontDescription.
- *
+ *
* Gets the variant field of a #PangoFontDescription. See
* pango_font_description_set_variant().
- *
+ *
* Return value: the variant field for the font description. Use
* pango_font_description_get_set_fields() to find out if
* the field was explicitly set or not.
pango_font_description_get_variant (const PangoFontDescription *desc)
{
g_return_val_if_fail (desc != NULL, pfd_defaults.variant);
-
+
return desc->variant;
}
* pango_font_description_set_weight:
* @desc: a #PangoFontDescription
* @weight: the weight for the font description.
- *
+ *
* Sets the weight field of a font description. The weight field
* specifies how bold or light the font should be. In addition
* to the values of the #PangoWeight enumeration, other intermediate
/**
* pango_font_description_get_weight:
* @desc: a #PangoFontDescription
- *
+ *
* Gets the weight field of a font description. See
* pango_font_description_set_weight().
- *
+ *
* Return value: the weight field for the font description. Use
* pango_font_description_get_set_fields() to find out if
* the field was explicitly set or not.
pango_font_description_get_weight (const PangoFontDescription *desc)
{
g_return_val_if_fail (desc != NULL, pfd_defaults.weight);
-
+
return desc->weight;
}
* pango_font_description_set_stretch:
* @desc: a #PangoFontDescription
* @stretch: the stretch for the font description
- *
+ *
* Sets the stretch field of a font description. The stretch field
* specifies how narrow or wide the font should be.
**/
PangoStretch stretch)
{
g_return_if_fail (desc != NULL);
-
+
desc->stretch = stretch;
desc->mask |= PANGO_FONT_MASK_STRETCH;
}
/**
* pango_font_description_get_stretch:
* @desc: a #PangoFontDescription.
- *
+ *
* Gets the stretch field of a font description.
* See pango_font_description_set_stretch().
- *
+ *
* Return value: the stretch field for the font description. Use
* pango_font_description_get_set_fields() to find out if
* the field was explicitly set or not.
* common, in which case a 10 point font corresponds to a 10 * (96 / 72) = 13.3
* pixel font. Use pango_font_description_set_absolute_size() if you need
* a particular size in device units.
- *
+ *
* Sets the size field of a font description in fractional points. This is mutually
- * exclusive with pango_font_description_set_absolute_size().
+ * exclusive with pango_font_description_set_absolute_size().
**/
void
pango_font_description_set_size (PangoFontDescription *desc,
{
g_return_if_fail (desc != NULL);
g_return_if_fail (size >= 0);
-
+
desc->size = size;
desc->size_is_absolute = FALSE;
desc->mask |= PANGO_FONT_MASK_SIZE;
/**
* pango_font_description_get_size:
* @desc: a #PangoFontDescription
- *
+ *
* Gets the size field of a font description.
* See pango_font_description_set_size().
- *
+ *
* Return value: the size field for the font description in points or device units.
* You must call pango_font_description_get_size_is_absolute()
* to find out which is the case. Returns 0 if the size field has not
* @size: the new size, in Pango units. There are %PANGO_SCALE Pango units in one
* device unit. For an output backend where a device unit is a pixel, a @size
* value of 10 * PANGO_SCALE gives a 10 pixel font.
- *
+ *
* Sets the size field of a font description, in device units. This is mutually
* exclusive with pango_font_description_set_size().
*
{
g_return_if_fail (desc != NULL);
g_return_if_fail (size >= 0);
-
+
desc->size = size;
desc->size_is_absolute = TRUE;
desc->mask |= PANGO_FONT_MASK_SIZE;
/**
* pango_font_description_get_size_is_absolute:
* @desc: a #PangoFontDescription
- *
+ *
* Determines whether the size of the font is in points or device units.
* See pango_font_description_set_size() and pango_font_description_set_absolute_size().
- *
+ *
* Return value: whether the size for the font description is in
* points or device units. Use pango_font_description_get_set_fields() to
* find out if the size field of the font description was explicitly set or not.
* pango_font_description_set_gravity:
* @desc: a #PangoFontDescription
* @gravity: the gravity for the font description.
- *
+ *
* Sets the gravity field of a font description. The gravity field
* specifies how the glyphs should be rotated. If @gravity is
* %PANGO_GRAVITY_AUTO, this actually unsets the gravity mask on
/**
* pango_font_description_get_gravity:
* @desc: a #PangoFontDescription
- *
+ *
* Gets the gravity field of a font description. See
* pango_font_description_set_gravity().
- *
+ *
* Return value: the gravity field for the font description. Use
* pango_font_description_get_set_fields() to find out if
* the field was explicitly set or not.
pango_font_description_get_gravity (const PangoFontDescription *desc)
{
g_return_val_if_fail (desc != NULL, pfd_defaults.gravity);
-
+
return desc->gravity;
}
/**
* pango_font_description_get_set_fields:
* @desc: a #PangoFontDescription
- *
+ *
* Determines which fields in a font description have been set.
- *
+ *
* Return value: a bitmask with bits set corresponding to the
* fields in @desc that have been set.
**/
* pango_font_description_unset_fields:
* @desc: a #PangoFontDescription
* @to_unset: bitmask of fields in the @desc to unset.
- *
+ *
* Unsets some of the fields in a #PangoFontDescription. The unset
* fields will get back to their default values.
**/
PangoFontMask to_unset)
{
PangoFontDescription unset_desc;
-
+
g_return_if_fail (desc != NULL);
unset_desc = pfd_defaults;
* @replace_existing: if %TRUE, replace fields in @desc with the
* corresponding values from @desc_to_merge, even if they
* are already exist.
- *
+ *
* Merges the fields that are set in @desc_to_merge into the fields in
* @desc. If @replace_existing is %FALSE, only fields in @desc that
* are not already set are affected. If %TRUE, then fields that are
gboolean replace_existing)
{
PangoFontMask new_mask;
-
+
g_return_if_fail (desc != NULL);
if (replace_existing)
* @desc: a #PangoFontDescription
* @old_match: a #PangoFontDescription, or %NULL
* @new_match: a #PangoFontDescription
- *
+ *
* Determines if the style attributes of @new_match are a closer match
* for @desc than @old_match, or if @old_match is %NULL, determines if
* @new_match is a match at all. Approximate matching is done for
* weight and style; other attributes must match exactly.
- *
+ *
* Return value: %TRUE if @new_match is a better match
**/
gboolean
{
g_return_val_if_fail (desc != NULL, G_MAXINT);
g_return_val_if_fail (new_match != NULL, G_MAXINT);
-
+
if (new_match->variant == desc->variant &&
new_match->stretch == desc->stretch &&
new_match->gravity == desc->gravity)
/**
* pango_font_description_copy:
* @desc: a #PangoFontDescription
- *
+ *
* Make a copy of a #PangoFontDescription.
- *
+ *
* Return value: the newly allocated #PangoFontDescription, which should
* be freed with pango_font_description_free().
**/
/**
* pango_font_description_copy_static:
* @desc: a #PangoFontDescription
- *
+ *
* Like pango_font_description_copy(), but only a shallow copy is made
* of the family name and other allocated fields. The result can only
* be used until @desc is modified or freed. This is meant to be used
* when the copy is only needed temporarily.
- *
+ *
* Return value: the newly allocated #PangoFontDescription, which should
* be freed with pango_font_description_free().
**/
* pango_font_description_equal:
* @desc1: a #PangoFontDescription
* @desc2: another #PangoFontDescription
- *
+ *
* Compares two font descriptions for equality. Two font descriptions
* are considered equal if the fonts they describe are provably identical.
* This means that their masks do not have to match, as long as other fields
* are all the same. (Two font descriptions may result in identical fonts
* being loaded, but still compare %FALSE.)
- *
+ *
* Return value: %TRUE if the two font descriptions are identical,
* %FALSE otherwise.
**/
/**
* pango_font_description_hash:
* @desc: a #PangoFontDescription
- *
+ *
* Computes a hash of a #PangoFontDescription structure suitable
* to be used, for example, as an argument to g_hash_table_new().
* The hash value is independent of @desc->mask.
- *
+ *
* Return value: the hash value.
**/
guint
/**
* pango_font_description_free:
* @desc: a #PangoFontDescription
- *
+ *
* Frees a font description.
**/
-void
+void
pango_font_description_free (PangoFontDescription *desc)
{
if (desc)
* pango_font_descriptions_free:
* @descs: a pointer to an array of #PangoFontDescription
* @n_descs: number of font descriptions in @descs
- *
+ *
* Frees a list of font descriptions from pango_font_map_list_fonts()
**/
void
find_field (const FieldMap *map, int n_elements, const char *str, int len, int *val)
{
int i;
-
+
for (i=0; i<n_elements; i++)
{
if (map[i].str[0] && g_ascii_strncasecmp (map[i].str, str, len) == 0 &&
if (g_ascii_strcasecmp (str, "Normal") == 0)
return TRUE;
-
+
#define FIELD(NAME, MASK) \
G_STMT_START { \
if (find_field (NAME##_map, G_N_ELEMENTS (NAME##_map), str, len, \
getword (const char *str, const char *last, size_t *wordlen)
{
const char *result;
-
+
while (last > str && g_ascii_isspace (*(last - 1)))
last--;
result--;
*wordlen = last - result;
-
+
return result;
}
/**
* pango_font_description_from_string:
* @str: string representation of a font description.
- *
+ *
* Creates a new font description from a string representation in the
* form "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]", where FAMILY-LIST is a
* comma separated list of families optionally terminated by a comma,
* STYLE-OPTIONS is missing, then all style options will be set to the
* default values. If SIZE is missing, the size in the resulting font
* description will be set to 0.
- *
- * Return value: a new #PangoFontDescription.
+ *
+ * Return value: a new #PangoFontDescription.
**/
PangoFontDescription *
pango_font_description_from_string (const char *str)
PANGO_FONT_MASK_WEIGHT |
PANGO_FONT_MASK_VARIANT |
PANGO_FONT_MASK_STRETCH;
-
+
len = strlen (str);
last = str + len;
p = getword (str, last, &wordlen);
if (str != last)
{
desc->family_name = g_strndup (str, last - str);
- desc->mask |= PANGO_FONT_MASK_FAMILY;
+ desc->mask |= PANGO_FONT_MASK_FAMILY;
}
return desc;
return;
}
}
-
+
if (str->len > 0 || str->str[str->len -1] != ' ')
g_string_append_c (str, ' ');
g_string_append_printf (str, "%d", val);
/**
* pango_font_description_to_string:
* @desc: a #PangoFontDescription
- *
+ *
* Creates a string representation of a font description. See
* pango_font_description_from_string() for a description of the
* format of the string representation. The family list in the
* string description will only have a terminating comma if the
* last word of the list is a valid style option.
- *
+ *
* Return value: a new string that must be freed with g_free().
**/
char *
if (desc->mask & PANGO_FONT_MASK_SIZE)
{
char buf[G_ASCII_DTOSTR_BUF_SIZE];
-
+
if (result->len > 0 || result->str[result->len -1] != ' ')
g_string_append_c (result, ' ');
if (desc->size_is_absolute)
g_string_append (result, "px");
}
-
+
return g_string_free (result, FALSE);
}
/**
* pango_font_description_to_filename:
* @desc: a #PangoFontDescription
- *
+ *
* Creates a filename representation of a font description. The
* filename is identical to the result from calling
* pango_font_description_to_string(), but with underscores instead of
}
return result;
-}
+}
G_DEFINE_TYPE (PangoFont, pango_font, G_TYPE_OBJECT)
/**
* pango_font_describe:
* @font: a #PangoFont
- *
+ *
* Returns a description of the font, with font size set in points.
* Use pango_font_describe_with_absolute_size() if you want the font
* size in device units.
- *
+ *
* Return value: a newly-allocated #PangoFontDescription object.
**/
PangoFontDescription *
/**
* pango_font_describe_with_absolute_size:
* @font: a #PangoFont
- *
+ *
* Returns a description of the font, with absolute font size set
* (in device units). Use pango_font_describe() if you want the font
* size in points.
- *
+ *
* Return value: a newly-allocated #PangoFontDescription object.
*
* Since: 1.14
* pango_font_get_coverage:
* @font: a #PangoFont
* @language: the language tag
- *
+ *
* Computes the coverage map for a given font and language tag.
- *
+ *
* Return value: a newly-allocated #PangoCoverage object.
**/
PangoCoverage *
* @font: a #PangoFont
* @language: the language tag
* @ch: a Unicode character.
- *
+ *
* Finds the best matching shaper for a font for a particular
* language tag and character point.
- *
+ *
* Return value: the best matching shaper.
**/
PangoEngineShape *
guint32 ch)
{
PangoEngineShape* shaper;
-
+
g_return_val_if_fail (font != NULL, NULL);
shaper = PANGO_FONT_GET_CLASS (font)->find_shaper (font, language, ch);
* or %NULL to indicate that the result is not needed.
* @logical_rect: rectangle used to store the logical extents of the glyph
* or %NULL to indicate that the result is not needed.
- *
+ *
* Gets the logical and ink extents of a glyph within a font. The
* coordinate system for each rectangle has its origin at the
* base line and horizontal origin of the character with increasing
{
if (G_UNLIKELY (!font))
{
-
+
if (!_pango_warning_history.get_glyph_extents)
{
_pango_warning_history.get_glyph_extents = TRUE;
* @language: language tag used to determine which script to get the metrics
* for, or %NULL to indicate to get the metrics for the entire
* font.
- *
+ *
* Gets overall metric information for a font. Since the metrics may be
* substantially different for different scripts, a language tag can
* be provided to indicate that the metrics should be retrieved that
{
if (G_UNLIKELY (!PANGO_IS_FONT (font)))
{
-
+
if (!_pango_warning_history.get_metrics)
{
_pango_warning_history.get_metrics = TRUE;
/**
* pango_font_get_font_map:
* @font: a #PangoFont
- *
+ *
* Gets the font map for which the font was created.
*
* Return value: the #PangoFontMap for the font
{
if (G_UNLIKELY (!PANGO_IS_FONT (font)))
{
-
+
if (!_pango_warning_history.get_font_map)
{
_pango_warning_history.get_font_map = TRUE;
pango_font_metrics_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoFontMetrics"),
(GBoxedCopyFunc)pango_font_metrics_ref,
/**
* pango_font_metrics_new:
- *
+ *
* Creates a new #PangoFontMetrics structure. This is only for
* internal use by Pango backends and there is no public way
* to set the fields of the structure.
- *
+ *
* Return value: a newly-created #PangoFontMetrics structure
* with a reference count of 1.
**/
/**
* pango_font_metrics_ref:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Increase the reference count of a font metrics structure by one.
- *
+ *
* Return value: @metrics
**/
PangoFontMetrics *
{
if (!metrics)
return NULL;
-
+
metrics->ref_count++;
return metrics;
/**
* pango_font_metrics_unref:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Decrease the reference count of a font metrics structure by one. If
* the result is zero, frees the structure and any associated
* memory.
if (!metrics)
return;
g_return_if_fail (metrics->ref_count > 0 );
-
+
metrics->ref_count--;
-
+
if (metrics->ref_count == 0)
g_slice_free (PangoFontMetrics, metrics);
}
/**
* pango_font_metrics_get_ascent:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the ascent from a font metrics structure. The ascent is
* the distance from the baseline to the logical top of a line
* of text. (The logical top may be above or below the top of the
* actual drawn ink. It is necessary to lay out the text to figure
* where the ink will be.)
- *
+ *
* Return value: the ascent, in Pango units. (1 point == %PANGO_SCALE Pango units.)
**/
int
/**
* pango_font_metrics_get_descent:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the descent from a font metrics structure. The descent is
* the distance from the baseline to the logical bottom of a line
* of text. (The logical bottom may be above or below the bottom of the
* actual drawn ink. It is necessary to lay out the text to figure
* where the ink will be.)
- *
+ *
* Return value: the descent, in Pango units. (1 point == %PANGO_SCALE Pango units.)
**/
int
/**
* pango_font_metrics_get_approximate_char_width:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the approximate character width for a font metrics structure.
* This is merely a representative value useful, for example, for
* determining the initial size for a window. Actual characters in
* text will be wider and narrower than this.
- *
+ *
* Return value: the character width, in Pango units. (1 point == %PANGO_SCALE Pango units.)
**/
int
/**
* pango_font_metrics_get_approximate_digit_width:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the approximate digit width for a font metrics structure.
* This is merely a representative value useful, for example, for
* determining the initial size for a window. Actual digits in
* text can be wider or narrower than this, though this value
* is generally somewhat more accurate than the result of
* pango_font_metrics_get_approximate_char_width() for digits.
- *
+ *
* Return value: the digit width, in Pango units. (1 point == %PANGO_SCALE Pango units.)
**/
int
/**
* pango_font_metrics_get_underline_position:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the suggested position to draw the underline.
* The value returned is the distance <emphasis>above</emphasis> the
* baseline of the top of the underline. Since most fonts have
* underline positions beneath the baseline, this value is typically
* negative.
- *
+ *
* Return value: the suggested underline position, in Pango units.
*
* Since: 1.6
/**
* pango_font_metrics_get_underline_thickness:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the suggested thickness to draw for the underline.
- *
+ *
* Return value: the suggested underline thickness, in Pango units.
*
* Since: 1.6
/**
* pango_font_metrics_get_strikethrough_position:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the suggested position to draw the strikethrough.
* The value returned is the distance <emphasis>above</emphasis> the
* baseline of the top of the strikethrough.
- *
+ *
* Return value: the suggested strikethrough position, in Pango units.
*
* Since: 1.6
/**
* pango_font_metrics_get_strikethrough_thickness:
* @metrics: a #PangoFontMetrics structure
- *
+ *
* Gets the suggested thickness to draw for the strikethrough.
- *
+ *
* Return value: the suggested strikethrough thickness, in Pango units.
*
* Since: 1.6
/**
* pango_font_family_get_name:
* @family: a #PangoFontFamily
- *
+ *
* Gets the name of the family. The name is unique among all
* fonts for the font backend and can be used in a #PangoFontDescription
* to specify that a face from this family is desired.
- *
+ *
* Return value: the name of the family. This string is owned
* by the family object and must not be modified or freed.
**/
* objects, or %NULL. This array should be freed with g_free()
* when it is no longer needed.
* @n_faces: location to store number of elements in @faces.
- *
+ *
* Lists the different font faces that make up @family. The faces
* in a family share a common design, but differ in slant, weight,
* width and other aspects.
**/
-void
+void
pango_font_family_list_faces (PangoFontFamily *family,
PangoFontFace ***faces,
int *n_faces)
* double-width characters: characters that occupy two grid cells.
* g_unichar_iswide() returns a result that indicates whether a
* character is typically double-width in a monospace font.
- *
+ *
* The best way to find out the grid-cell size is to call
* pango_font_metrics_get_approximate_digit_width(), since the results
* of pango_font_metrics_get_approximate_char_width() may be affected
- * by double-width characters.
- *
+ * by double-width characters.
+ *
* Return value: %TRUE if the family is monospace.
*
* Since: 1.4
**/
-gboolean
+gboolean
pango_font_family_is_monospace (PangoFontFamily *family)
{
g_return_val_if_fail (PANGO_IS_FONT_FAMILY (family), FALSE);
/**
* pango_font_face_describe:
* @face: a #PangoFontFace
- *
+ *
* Returns the family, style, variant, weight and stretch of
* a #PangoFontFace. The size field of the resulting font description
- * will be unset.
- *
+ * will be unset.
+ *
* Return value: a newly-created #PangoFontDescription structure
* holding the description of the face. Use pango_font_description_free()
* to free the result.
/**
* pango_font_face_get_face_name:
* @face: a #PangoFontFace.
- *
+ *
* Gets a name representing the style of this face among the
* different faces in the #PangoFontFamily for the face. This
* name is unique among all faces in the family and is suitable
* for displaying to users.
- *
+ *
* Return value: the face name for the face. This string is
* owned by the face object and must not be modified or freed.
**/
* @sizes: location to store a pointer to an array of int. This array
* should be freed with g_free().
* @n_sizes: location to store the number of elements in @sizes
- *
+ *
* List the available sizes for a font. This is only applicable to bitmap
* fonts. For scalable fonts, stores %NULL at the location pointed to by
* @sizes and 0 at the location pointed to by @n_sizes. The sizes returned
* Since: 1.4
**/
void
-pango_font_face_list_sizes (PangoFontFace *face,
- int **sizes,
+pango_font_face_list_sizes (PangoFontFace *face,
+ int **sizes,
int *n_sizes)
{
g_return_if_fail (PANGO_IS_FONT_FACE (face));
string->space = 1;
else
string->space *= 2;
-
+
if (string->space < 0)
{
g_warning ("glyph string length overflows maximum integer size, truncated");
new_len = string->space = G_MAXINT - 8;
}
}
-
+
string->glyphs = g_realloc (string->glyphs, string->space * sizeof (PangoGlyphInfo));
string->log_clusters = g_realloc (string->log_clusters, string->space * sizeof (gint));
string->num_glyphs = new_len;
pango_glyph_string_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoGlyphString"),
(GBoxedCopyFunc)pango_glyph_string_copy,
ink_rect->width = 0;
ink_rect->height = 0;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
logical_rect->width = 0;
logical_rect->height = 0;
}
-
+
for (i = start; i < end; i++)
{
PangoRectangle glyph_ink;
PangoRectangle glyph_logical;
-
+
PangoGlyphGeometry *geometry = &glyphs->glyphs[i].geometry;
pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph,
else
{
int new_x, new_y;
-
+
new_x = MIN (ink_rect->x, x_pos + glyph_ink.x + geometry->x_offset);
ink_rect->width = MAX (ink_rect->x + ink_rect->width,
x_pos + glyph_ink.x + glyph_ink.width + geometry->x_offset) - new_x;
ink_rect->x = new_x;
-
+
new_y = MIN (ink_rect->y, glyph_ink.y + geometry->y_offset);
ink_rect->height = MAX (ink_rect->y + ink_rect->height,
glyph_ink.y + glyph_ink.height + geometry->y_offset) - new_y;
x_pos += geometry->width;
}
}
-
+
/**
* pango_glyph_string_extents:
* @glyphs: a #PangoGlyphString
* or %NULL to indicate that the result is not needed.
* @logical_rect: rectangle used to store the logical extents of the glyph string
* or %NULL to indicate that the result is not needed.
- *
+ *
* Compute the logical and ink extents of a glyph string. See the documentation
* for pango_font_get_glyph_extents() for details about the interpretation
* of the rectangles.
*/
-void
+void
pango_glyph_string_extents (PangoGlyphString *glyphs,
PangoFont *font,
PangoRectangle *ink_rect,
/**
* pango_glyph_string_get_width:
* @glyphs: a #PangoGlyphString
- *
+ *
* Computes the logical width of the glyph string as can also be computed
* using pango_glyph_string_extents(). However, since this only computes the
* width, it's much faster. This is in fact only a convenience function that
int width = 0;
int last_cluster_width = 0;
const char *p = text; /* Points to start of current cluster */
-
+
for (i=0; i<=glyphs->num_glyphs; i++)
{
int glyph_index = (embedding_level % 2 == 0) ? i : glyphs->num_glyphs - i - 1;
if (i == glyphs->num_glyphs || p != text + glyphs->log_clusters[glyph_index])
{
int next_cluster = last_cluster;
-
+
if (i < glyphs->num_glyphs)
{
while (p < text + glyphs->log_clusters[glyph_index])
p = g_utf8_next_char (p);
}
}
-
+
for (j = last_cluster; j < next_cluster; j++)
logical_widths[j] = (width - last_cluster_width) / (next_cluster - last_cluster);
-
+
last_cluster = next_cluster;
last_cluster_width = width;
}
-
+
if (i < glyphs->num_glyphs)
width += glyphs->glyphs[glyph_index].geometry.width;
}
int cluster_offset = 0;
char *p;
-
+
g_return_if_fail (glyphs != NULL);
g_return_if_fail (length >= 0);
g_return_if_fail (length == 0 || text != NULL);
if (!x_pos) /* Allow the user to do the useless */
return;
-
+
if (glyphs->num_glyphs == 0)
{
*x_pos = 0;
start_index = glyphs->log_clusters[i];
start_xpos = width;
}
-
+
width += glyphs->glyphs[i].geometry.width;
}
}
cluster_chars++;
p = g_utf8_next_char (p);
}
-
+
if (trailing)
cluster_offset += 1;
* position; the caller must combine the result with the logical
* attributes for the text to compute the valid cursor position.
*/
-void
+void
pango_glyph_string_x_to_index (PangoGlyphString *glyphs,
char *text,
int length,
PangoAnalysis *analysis,
int x_pos,
- int *index,
+ int *index,
gboolean *trailing)
{
int i;
start_xpos = width;
}
}
-
+
if (width <= x_pos && x_pos < width + glyphs->glyphs[i].geometry.width)
found = TRUE;
-
+
width += glyphs->glyphs[i].geometry.width;
}
}
p = g_utf8_next_char (p);
cluster_chars++;
}
-
+
if (start_xpos == end_xpos)
{
if (index)
{
char *p = text + start_index;
int i = 0;
-
+
while (i + 1 <= cp)
{
p = g_utf8_next_char (p);
i++;
}
-
+
*index = (p - text);
}
-
+
if (trailing)
*trailing = (cp - (int)cp >= 0.5) ? 1 : 0;
}
{
char *p = text + start_index;
int i = 0;
-
+
while (i + 1 < cp)
{
p = g_utf8_next_char (p);
i++;
}
-
+
*index = (p - text);
}
-
+
if (trailing)
{
double cp_flip = cluster_chars - cp;
GArray *entries;
};
-struct _PangoMapEntry
+struct _PangoMapEntry
{
GSList *exact;
GSList *fallback;
PangoEngine *(*create) (const gchar *id);
};
-struct _PangoModuleClass
+struct _PangoModuleClass
{
GTypeModuleClass parent_class;
};
* @language: the language tag for which to find the map
* @engine_type_id: the engine type for the map to find
* @render_type_id: the render type for the map to find
- *
+ *
* Locate a #PangoMap for a particular engine type and render
* type. The resulting map can be used to determine the engine
* for each character.
- *
+ *
* Return value: the suitable #PangoMap.
**/
PangoMap *
maps = g_list_prepend(maps, tmp_list->data);
g_list_free_1(tmp_list);
}
-
+
return map_info->map;
}
g_warning ("%s", g_module_error());
return FALSE;
}
-
+
/* extract symbols from the lib */
if (!g_module_symbol (pango_module->library, "script_engine_init",
(gpointer *)&pango_module->init) ||
- !g_module_symbol (pango_module->library, "script_engine_exit",
+ !g_module_symbol (pango_module->library, "script_engine_exit",
(gpointer *)&pango_module->exit) ||
- !g_module_symbol (pango_module->library, "script_engine_list",
+ !g_module_symbol (pango_module->library, "script_engine_list",
(gpointer *)&pango_module->list) ||
- !g_module_symbol (pango_module->library, "script_engine_create",
+ !g_module_symbol (pango_module->library, "script_engine_create",
(gpointer *)&pango_module->create))
{
g_warning ("%s", g_module_error());
g_module_close (pango_module->library);
-
+
return FALSE;
}
}
-
+
/* call the module's init function to let it */
/* setup anything it needs to set up. */
pango_module->init (module);
{
g_module_close (pango_module->library);
pango_module->library = NULL;
-
+
pango_module->init = NULL;
pango_module->exit = NULL;
pango_module->list = NULL;
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
-
+
module_class->load = pango_module_load;
module_class->unload = pango_module_unload;
if (!warned_quark)
warned_quark = g_quark_from_static_string ("pango-module-warned");
-
+
if (!g_object_get_qdata (G_OBJECT (pair->module), warned_quark))
{
g_warning ("Failed to load Pango module '%s' for id '%s'", pair->module->path, pair->info.id);
pair->info = engine_info[i];
pair->module = module;
pair->engine = NULL;
-
+
*engine_list = g_slist_prepend (*engine_list, pair);
}
}
{
path = g_strdup (raw_path);
}
-
+
module = g_hash_table_lookup (dlloaded_modules, path);
if (module)
g_free (path);
GEnumValue *value;
if (!class)
class = g_type_class_ref (PANGO_TYPE_SCRIPT);
-
+
value = g_enum_get_value_by_nick (class, str);
if (!value)
return PANGO_SCRIPT_INVALID_CODE;
have_error = TRUE;
goto error;
}
-
+
script_info = g_slice_new (PangoEngineScriptInfo);
script_info->script = script;
script_info->langs = g_strdup (q + 1);
-
+
scripts = g_list_prepend (scripts, script_info);
}
if (!pango_skip_space (&p))
break;
-
+
i++;
}
-
+
if (i<3)
{
have_error = TRUE;
goto error;
}
-
+
scripts = g_list_reverse (scripts);
pair->info.n_scripts = g_list_length (scripts);
pair->info.scripts = g_new (PangoEngineScriptInfo, pair->info.n_scripts);
-
+
tmp_list = scripts;
for (i=0; i<pair->info.n_scripts; i++)
{
}
pair->engine = NULL;
-
+
dlloaded_engines = g_slist_prepend (dlloaded_engines, pair);
error:
int n;
dlloaded_modules = g_hash_table_new (g_str_hash, g_str_equal);
-
+
if (!file_str)
file_str = g_build_filename (pango_get_sysconf_subdirectory (),
"pango.modules",
return;
else
init = TRUE;
-
+
/* Make sure that the type system is initialized */
g_type_init ();
-
+
for (i = 0; _pango_included_lang_modules[i].list; i++)
pango_module_register (&_pango_included_lang_modules[i]);
read_modules ();
{
PangoMap *map = info->map;
int i;
-
+
for (i=0; i<pair->info.n_scripts; i++)
{
PangoScript script;
map_add_engine_list (PangoMapInfo *info,
GSList *engines,
const char *engine_type,
- const char *render_type)
+ const char *render_type)
{
GSList *tmp_list = engines;
{
const char *engine_type = g_quark_to_string (info->engine_type_id);
const char *render_type = g_quark_to_string (info->render_type_id);
-
+
init_modules();
if (!dlloaded_engines && !registered_engines)
"You should create this file by running pango-querymodules.",
filename);
g_free (filename);
-
+
no_module_warning = TRUE;
}
}
-
+
info->map = g_slice_new (PangoMap);
info->map->entries = g_array_new (FALSE, TRUE, sizeof (PangoMapEntry));
-
- map_add_engine_list (info, dlloaded_engines, engine_type, render_type);
- map_add_engine_list (info, registered_engines, engine_type, render_type);
+
+ map_add_engine_list (info, dlloaded_engines, engine_type, render_type);
+ map_add_engine_list (info, registered_engines, engine_type, render_type);
}
/**
* pango_map_get_engine:
* @map: a #PangoMap
* @script: a #PangoScript
- *
+ *
* Returns the best engine listed in the map for a given script
- *
+ *
* Return value: the best engine, if one is listed for the script,
* or %NULL. The lookup may cause the engine to be loaded;
* once an engine is loaded, it won't be unloaded. If multiple
{
PangoMapEntry *entry = NULL;
PangoMapEntry *common_entry = NULL;
-
+
if ((guint)script < map->entries->len)
entry = &g_array_index (map->entries, PangoMapEntry, script);
* handle this script.
* @fallback_engines: location to store list of engines that approximately
* handle this script.
- *
+ *
* Finds engines in the map that handle the given script. The returned
* lists should be freed with g_slist_free, but the engines in the
* lists are owned by GLib and will be kept around permanently, so
{
PangoMapEntry *entry = NULL;
PangoMapEntry *common_entry = NULL;
-
+
if ((guint)script < map->entries->len)
entry = &g_array_index (map->entries, PangoMapEntry, script);
else if (common_entry && common_entry->exact)
append_engines (exact_engines, common_entry->exact);
}
-
+
if (fallback_engines)
{
*fallback_engines = NULL;
/**
* pango_module_register:
* @module: a #PangoIncludedModule
- *
+ *
* Registers a statically linked module with Pango. The
* #PangoIncludedModule structure that is passed in contains the
* functions that would otherwise be loaded from a dynamically loaded
pango_module_register (PangoIncludedModule *module)
{
GSList *tmp_list = NULL;
-
+
handle_included_module (module, &tmp_list);
registered_engines = g_slist_concat (registered_engines,
- g_slist_reverse (tmp_list));
+ g_slist_reverse (tmp_list));
}
/**
* pango_attr_type_register:
* @name: an identifier for the type (currently unused.)
- *
+ *
* Allocate a new attribute type ID.
- *
+ *
* Return value: the new type ID.
**/
PangoAttrType
/**
* pango_attribute_copy:
* @attr: a #PangoAttribute
- *
+ *
* Make a copy of an attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attribute_destroy:
* @attr: a #PangoAttribute.
- *
+ *
* Destroy a #PangoAttribute and free all associated memory.
**/
void
* pango_attribute_equal:
* @attr1: a #PangoAttribute
* @attr2: another #PangoAttribute
- *
+ *
* Compare two attributes for equality. This compares only the
* actual value of the two attributes and not the ranges that the
* attributes apply to.
- *
+ *
* Return value: %TRUE if the two attributes have the same value.
**/
gboolean
/**
* pango_attr_family_new:
* @family: the family or comma separated list of families
- *
+ *
* Create a new font family attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
};
g_return_val_if_fail (family != NULL, NULL);
-
+
return pango_attr_string_new (&klass, family);
}
/**
* pango_attr_language_new:
* @language: language tag
- *
- * Create a new language tag attribute.
- *
+ *
+ * Create a new language tag attribute.
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
pango_attr_language_new (PangoLanguage *language)
{
PangoAttrLanguage *result;
-
+
static const PangoAttrClass klass = {
PANGO_ATTR_LANGUAGE,
pango_attr_language_copy,
};
g_return_val_if_fail (language != NULL, NULL);
-
+
result = g_slice_new (PangoAttrLanguage);
result->attr.klass = &klass;
pango_attr_color_copy (const PangoAttribute *attr)
{
const PangoAttrColor *color_attr = (PangoAttrColor *)attr;
-
+
return pango_attr_color_new (attr->klass,
color_attr->color.red,
color_attr->color.green,
* @red: the red value (ranging from 0 to 65535)
* @green: the green value
* @blue: the blue value
- *
+ *
* Create a new foreground color attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
* @red: the red value (ranging from 0 to 65535)
* @green: the green value
* @blue: the blue value
- *
+ *
* Create a new background color attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
pango_attr_int_copy (const PangoAttribute *attr)
{
const PangoAttrInt *int_attr = (PangoAttrInt *)attr;
-
+
return pango_attr_int_new (attr->klass, int_attr->value);
}
{
const PangoAttrInt *int_attr1 = (const PangoAttrInt *)attr1;
const PangoAttrInt *int_attr2 = (const PangoAttrInt *)attr2;
-
+
return (int_attr1->value == int_attr2->value);
}
pango_attr_float_copy (const PangoAttribute *attr)
{
const PangoAttrFloat *float_attr = (PangoAttrFloat *)attr;
-
+
return pango_attr_float_new (attr->klass, float_attr->value);
}
{
const PangoAttrFloat *float_attr1 = (const PangoAttrFloat *)attr1;
const PangoAttrFloat *float_attr2 = (const PangoAttrFloat *)attr2;
-
+
return (float_attr1->value == float_attr2->value);
}
{
const PangoAttrSize *size_attr1 = (const PangoAttrSize *)attr1;
const PangoAttrSize *size_attr2 = (const PangoAttrSize *)attr2;
-
+
return size_attr1->size == size_attr2->size;
}
gboolean absolute)
{
PangoAttrSize *result;
-
+
static const PangoAttrClass klass = {
PANGO_ATTR_SIZE,
pango_attr_size_copy,
/**
* pango_attr_size_new:
* @size: the font size, in %PANGO_SCALE<!-- -->ths of a point.
- *
+ *
* Create a new font-size attribute in fractional points.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_size_new_absolute:
* @size: the font size, in %PANGO_SCALE<!-- -->ths of a device unit.
- *
+ *
* Create a new font-size attribute in device units.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
/**
* pango_attr_style_new:
* @style: the slant style
- *
+ *
* Create a new font slant style attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_weight_new:
* @weight: the weight
- *
+ *
* Create a new font weight attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
* @variant: the variant
*
* Create a new font variant attribute (normal or small caps)
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_stretch_new:
* @stretch: the stretch
- *
+ *
* Create a new font stretch attribute
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
pango_attr_font_desc_copy (const PangoAttribute *attr)
{
const PangoAttrFontDesc *desc_attr = (const PangoAttrFontDesc *)attr;
-
+
return pango_attr_font_desc_new (desc_attr->desc);
}
{
const PangoAttrFontDesc *desc_attr1 = (const PangoAttrFontDesc *)attr1;
const PangoAttrFontDesc *desc_attr2 = (const PangoAttrFontDesc *)attr2;
-
+
return pango_font_description_equal (desc_attr1->desc, desc_attr2->desc);
}
/**
* pango_attr_font_desc_new:
* @desc: the font description
- *
+ *
* Create a new font description attribute. This attribute
* allows setting family, style, weight, variant, stretch,
* and size simultaneously.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_underline_new:
* @underline: the underline style.
- *
+ *
* Create a new underline-style attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
* @red: the red value (ranging from 0 to 65535)
* @green: the green value
* @blue: the blue value
- *
+ *
* Create a new underline color attribute. This attribute
* modifies the color of underlines. If not set, underlines
* will use the foreground color.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
/**
* pango_attr_strikethrough_new:
* @strikethrough: %TRUE if the text should be struck-through.
- *
+ *
* Create a new strike-through attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
* @red: the red value (ranging from 0 to 65535)
* @green: the green value
* @blue: the blue value
- *
+ *
* Create a new strikethrough color attribute. This attribute
* modifies the color of strikethrough lines. If not set, strikethrough
* lines will use the foreground color.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
* pango_attr_rise_new:
* @rise: the amount that the text should be displaced vertically,
* in Pango units. Positive values displace the text upwards.
- *
+ *
* Create a new baseline displacement attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_scale_new:
* @scale_factor: factor to scale the font
- *
+ *
* Create a new font size scale attribute. The base font for the
* affected text will have its size multiplied by @scale_factor.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_fallback_new:
- * @enable_fallback: %TRUE if we should fall back on other fonts
+ * @enable_fallback: %TRUE if we should fall back on other fonts
* for characters the active font is missing.
- *
+ *
* Create a new font fallback attribute.
*
* If fallback is disabled, characters will only be used from the
* closest matching font on the system. No fallback will be done to
* other fonts on the system that might contain the characters in the
* text.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
* pango_attr_letter_spacing_new:
* @letter_spacing: amount of extra space to add between graphemes
* of the text, in Pango units.
- *
+ *
* Create a new letter-spacing attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
data = shape_attr->copy_func (shape_attr->data);
else
data = shape_attr->data;
-
+
return pango_attr_shape_new_with_data (&shape_attr->ink_rect, &shape_attr->logical_rect,
data, shape_attr->copy_func, shape_attr->destroy_func);
}
pango_attr_shape_destroy (PangoAttribute *attr)
{
PangoAttrShape *shape_attr = (PangoAttrShape *)attr;
-
+
if (shape_attr->destroy_func)
shape_attr->destroy_func (shape_attr->data);
-
+
g_slice_free (PangoAttrShape, shape_attr);
}
* as a pointer.
* @destroy_func: function to free @data when the attribute
* is freed, or %NULL
- *
+ *
* Like pango_attr_shape_new(), but a user data pointer is also
* provided; this pointer can be accessed when later
* rendering the glyph.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
g_return_val_if_fail (ink_rect != NULL, NULL);
g_return_val_if_fail (logical_rect != NULL, NULL);
-
+
result = g_slice_new (PangoAttrShape);
result->attr.klass = &klass;
result->ink_rect = *ink_rect;
* pango_attr_shape_new:
* @ink_rect: ink rectangle to assign to each character
* @logical_rect: logical rectangle to assign to each character
- *
+ *
* Create a new shape attribute. A shape is used to impose a
* particular ink and logical rectangle on the result of shaping a
* particular glyph. This might be used, for instance, for
* embedding a picture or a widget inside a #PangoLayout.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
**/
/**
* pango_attr_gravity_new:
* @gravity: the gravity value; should not be %PANGO_GRAVITY_AUTO.
- *
+ *
* Create a new gravity attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
/**
* pango_attr_gravity_hint_new:
* @hint: the gravity hint value.
- *
+ *
* Create a new gravity hint attribute.
- *
+ *
* Return value: the newly allocated #PangoAttribute, which should be
* freed with pango_attribute_destroy().
*
pango_attr_list_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoAttrList"),
(GBoxedCopyFunc) pango_attr_list_copy,
/**
* pango_attr_list_new:
- *
+ *
* Create a new empty attribute list with a reference count of one.
- *
+ *
* Return value: the newly allocated #PangoAttrList, which should
* be freed with pango_attr_list_unref().
**/
list->ref_count = 1;
list->attributes = NULL;
list->attributes_tail = NULL;
-
+
return list;
}
/**
* pango_attr_list_ref:
* @list: a #PangoAttrList
- *
+ *
* Increase the reference count of the given attribute list by one.
*
* Return value: The attribute list passed in
/**
* pango_attr_list_unref:
* @list: a #PangoAttrList
- *
+ *
* Decrease the reference count of the given attribute list by one.
* If the result is zero, free the attribute list and the attributes
* it contains.
pango_attr_list_unref (PangoAttrList *list)
{
GSList *tmp_list;
-
+
g_return_if_fail (list != NULL);
g_return_if_fail (list->ref_count > 0);
/**
* pango_attr_list_copy:
* @list: a #PangoAttrList
- *
+ *
* Copy @list and return an identical new list.
*
* Return value: the newly allocated #PangoAttrList, with a
PangoAttrList *new;
GSList *iter;
GSList *new_attrs;
-
+
g_return_val_if_fail (list != NULL, NULL);
new = pango_attr_list_new ();
/* we're going to reverse the nodes, so head becomes tail */
new->attributes_tail = new_attrs;
new->attributes = g_slist_reverse (new_attrs);
-
+
return new;
}
while (1)
{
PangoAttribute *tmp_attr = tmp_list->data;
-
+
if (tmp_attr->start_index > start_index ||
(before && tmp_attr->start_index == start_index))
{
break;
}
-
+
prev = tmp_list;
tmp_list = tmp_list->next;
}
* @list: a #PangoAttrList
* @attr: the attribute to insert. Ownership of this value is
* assumed by the list.
- *
+ *
* Insert the given attribute into the #PangoAttrList. It will
* be inserted after all other attributes with a matching
* @start_index.
* @list: a #PangoAttrList
* @attr: the attribute to insert. Ownership of this value is
* assumed by the list.
- *
+ *
* Insert the given attribute into the #PangoAttrList. It will
* be inserted before all other attributes with a matching
* @start_index.
* @list: a #PangoAttrList
* @attr: the attribute to insert. Ownership of this value is
* assumed by the list.
- *
+ *
* Insert the given attribute into the #PangoAttrList. It will
* replace any attributes of the same type on that segment
* and be merged with any adjoining attributes that are identical.
* This function is slower than pango_attr_list_insert() for
* creating a attribute list in order (potentially much slower
* for large lists). However, pango_attr_list_insert() is not
- * suitable for continually changing a set of attributes
+ * suitable for continually changing a set of attributes
* since it never removes or combines existing attributes.
**/
void
pango_attribute_destroy (attr);
return;
}
-
+
tmp_list = list->attributes;
prev = NULL;
while (1)
link = g_slist_alloc ();
link->next = tmp_list;
link->data = attr;
-
+
if (prev)
prev->next = link;
else
list->attributes = link;
-
+
if (!tmp_list)
list->attributes_tail = link;
-
+
prev = link;
tmp_list = prev->next;
break;
}
tmp_attr->end_index = end_index;
pango_attribute_destroy (attr);
-
+
attr = tmp_attr;
-
+
prev = tmp_list;
tmp_list = tmp_list->next;
-
+
break;
}
else
g_assert (prev->data == attr);
g_assert (prev->next == tmp_list);
-
+
/* We now have the range inserted into the list one way or the
* other. Fix up the remainder
*/
/* We can merge the new attribute with this attribute.
*/
attr->end_index = MAX (end_index, tmp_attr->end_index);
-
+
pango_attribute_destroy (tmp_attr);
prev->next = tmp_list->next;
if (!prev->next)
list->attributes_tail = prev;
-
+
g_slist_free_1 (tmp_list);
tmp_list = prev->next;
*/
GSList *tmp_list2;
GSList *prev2;
-
+
tmp_attr->start_index = attr->end_index;
tmp_list2 = tmp_list->next;
if (prev2 != tmp_list)
{
GSList *old_next = tmp_list->next;
-
+
prev->next = old_next;
prev2->next = tmp_list;
tmp_list->next = tmp_list2;
}
}
}
-
+
prev = tmp_list;
tmp_list = tmp_list->next;
}
* @len: the length of the spliced segment. (Note that this
* must be specified since the attributes in @other
* may only be present at some subsection of this range)
- *
+ *
* This function opens up a hole in @list, fills it in with attributes from
* the left, and then merges @other on top of the hole.
*
{
GSList *tmp_list;
guint upos, ulen;
-
+
g_return_if_fail (list != NULL);
- g_return_if_fail (other != NULL);
+ g_return_if_fail (other != NULL);
g_return_if_fail (pos >= 0);
g_return_if_fail (len >= 0);
* isn't defined in the C standard for signed integers
*/
#define CLAMP_ADD(a,b) (((a) + (b) < (a)) ? G_MAXUINT : (a) + (b))
-
+
tmp_list = list->attributes;
while (tmp_list)
{
* pango_attr_list_change() will take care of deleting it.
*/
pango_attr_list_change (list, attr);
-
+
tmp_list = tmp_list->next;
}
#undef CLAMP_ADD
/**
* pango_attr_list_get_iterator:
* @list: a #PangoAttrList
- *
+ *
* Create a iterator initialized to the beginning of the list.
* @list must not be modified until this iterator is freed.
- *
+ *
* Return value: the newly allocated #PangoAttrIterator, which should
* be freed with pango_attr_iterator_destroy().
**/
* @iterator: a #PangoAttrIterator
* @start: location to store the start of the range
* @end: location to store the end of the range
- *
+ *
* Get the range of the current segment. Note that the
* stored return values are signed, not unsigned like
* the values in #PangoAttribute. To deal with this API
/**
* pango_attr_iterator_next:
* @iterator: a #PangoAttrIterator
- *
+ *
* Advance the iterator until the next change of style.
- *
+ *
* Return value: %FALSE if the iterator is at the end of the list, otherwise %TRUE
**/
gboolean
iterator->start_index = iterator->end_index;
iterator->end_index = G_MAXUINT;
-
+
tmp_list = iterator->attribute_stack;
while (tmp_list)
{
{
iterator->end_index = MIN (iterator->end_index, attr->end_index);
}
-
+
tmp_list = next;
}
/**
* pango_attr_iterator_copy:
* @iterator: a #PangoAttrIterator.
- *
+ *
* Copy a #PangoAttrIterator
*
* Return value: the newly allocated #PangoAttrIterator, which should
/**
* pango_attr_iterator_destroy:
* @iterator: a #PangoAttrIterator.
- *
+ *
* Destroy a #PangoAttrIterator and free all associated memory.
**/
void
pango_attr_iterator_destroy (PangoAttrIterator *iterator)
{
g_return_if_fail (iterator != NULL);
-
+
g_list_free (iterator->attribute_stack);
g_slice_free (PangoAttrIterator, iterator);
}
* pango_attr_iterator_get:
* @iterator: a #PangoAttrIterator
* @type: the type of attribute to find.
- *
+ *
* Find the current attribute of a particular type at the iterator
* location. When multiple attributes of the same type overlap,
* the attribute whose range starts closest to the current location
* is used.
- *
+ *
* Return value: the current attribute of the given type, or %NULL
* if no attribute of that type applies to the current
* location.
g_return_if_fail (iterator != NULL);
g_return_if_fail (desc != NULL);
-
+
if (language)
*language = NULL;
-
+
if (extra_attrs)
*extra_attrs = NULL;
-
+
tmp_list1 = iterator->attribute_stack;
while (tmp_list1)
{
mask |= new_mask;
pango_font_description_unset_fields (desc, new_mask);
pango_font_description_merge_static (desc, ((PangoAttrFontDesc *)attr)->desc, FALSE);
-
+
break;
}
case PANGO_ATTR_FAMILY:
if (extra_attrs)
{
gboolean found = FALSE;
-
+
tmp_list2 = *extra_attrs;
while (tmp_list2)
{
* @func: callback function; returns %TRUE if an attribute
* should be filtered out.
* @data: Data to be passed to @func
- *
+ *
* Given a #PangoAttrList and callback function, removes any elements
* of @list for which @func returns %TRUE and inserts them into
* a new list.
- *
+ *
* Return value: the new #PangoAttrList or %NULL if
* no attributes of the given types were found.
*
PangoAttrList *new = NULL;
GSList *tmp_list;
GSList *prev;
-
+
g_return_val_if_fail (list != NULL, NULL);
tmp_list = list->attributes;
{
if (!tmp_list->next)
list->attributes_tail = prev;
-
+
if (prev)
prev->next = tmp_list->next;
else
list->attributes = tmp_list->next;
-
+
tmp_list->next = NULL;
-
+
if (!new)
{
new = pango_attr_list_new ();
/**
* pango_attr_iterator_get_attrs:
* @iterator: a #PangoAttrIterator
- *
+ *
* Gets a list of all attributes at the current position of the
* iterator.
- *
+ *
* Return value: a list of all attributes for the current range.
* To free this value, call pango_attribute_destroy() on
* each value and g_slist_free() on the list.
typedef struct _PangoAttribute PangoAttribute;
typedef struct _PangoAttrClass PangoAttrClass;
-
+
typedef struct _PangoAttrString PangoAttrString;
typedef struct _PangoAttrLanguage PangoAttrLanguage;
typedef struct _PangoAttrInt PangoAttrInt;
PangoAttribute attr;
PangoRectangle ink_rect;
PangoRectangle logical_rect;
-
+
gpointer data;
PangoAttrDataCopyFunc copy_func;
GDestroyNotify destroy_func;
guint is_mandatory_break : 1; /* Must break line in front of character */
guint is_char_break : 1; /* Can break here when doing char wrap */
-
+
guint is_white : 1; /* Whitespace character */
/* cursor can appear in front of character (i.e. this is a grapheme
* boundary, or the first character in the text)
*/
guint is_cursor_position : 1;
-
+
/* Note that in degenerate cases, you could have both start/end set on
* some text, most likely for sentences (e.g. no space after a period, so
* the next sentence starts right away)
*/
-
+
guint is_word_start : 1; /* first character in a word */
guint is_word_end : 1; /* is first non-word char after a word */
guint is_sentence_end : 1; /* first non-sentence char after a sentence */
/* if set, backspace deletes one character rather than
- * the entire grapheme cluster
+ * the entire grapheme cluster
*/
- guint backspace_deletes_character : 1;
+ guint backspace_deletes_character : 1;
};
/* Determine information about cluster/word/line breaks in a string
* of Unicode text.
*/
-void pango_break (const gchar *text,
- int length,
- PangoAnalysis *analysis,
+void pango_break (const gchar *text,
+ int length,
+ PangoAnalysis *analysis,
PangoLogAttr *attrs,
int attrs_len);
*
* Date: Fri Mar 4 23:40:25 2005
*
- * Do not edit.
+ * Do not edit.
*/
static const char color_names[] =
"alice blue\0"
pango_color_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoColor"),
(GBoxedCopyFunc) pango_color_copy,
/**
* pango_color_copy:
* @src: color to copy
- *
+ *
* Creates a copy of @src, which should be freed with
* pango_color_free(). Primarily used by language bindings,
* not that useful otherwise (since colors can just be copied
* by assignment in C).
- *
+ *
* Return value: the newly allocated #PangoColor, which should
* be freed with pango_color_free().
**/
PangoColor *ret;
g_return_val_if_fail (src != NULL, NULL);
-
+
ret = g_slice_new (PangoColor);
*ret = *src;
/**
* pango_color_free:
* @color: an allocated #PangoColor
- *
+ *
* Frees a color allocated by pango_color_copy().
**/
void
return TRUE;
}
-static gboolean
-hex (const char *spec,
- int len,
+static gboolean
+hex (const char *spec,
+ int len,
unsigned int *c)
{
const char *end;
- *c = 0;
+ *c = 0;
for (end = spec + len; spec != end; spec++)
if (g_ascii_isxdigit (*spec))
*c = (*c << 4) | g_ascii_xdigit_value (*spec);
* pango_color_parse:
* @color: a #PangoColor structure in which to store the result
* @spec: a string specifying the new color
- *
+ *
* Fill in the fields of a color from a string specification. The
* string can either one of a large set of standard names. (Taken
* from the X11 <filename>rgb.txt</filename> file), or it can be a hex value in the
len = strlen (spec);
if (len % 3 || len < 3 || len > 12)
return FALSE;
-
+
len /= 3;
- if (!hex (spec, len, &r) ||
+ if (!hex (spec, len, &r) ||
!hex (spec + len, len, &g) ||
!hex (spec + len * 2, len, &b))
return FALSE;
r |= (r >> bits);
g |= (g >> bits);
b |= (b >> bits);
- bits *= 2;
+ bits *= 2;
}
color->red = r;
color->green = g;
struct _PangoContextClass
{
GObjectClass parent_class;
-
+
};
static void pango_context_finalize (GObject *object);
context->base_dir = PANGO_DIRECTION_WEAK_LTR;
context->resolved_gravity = context->base_gravity = PANGO_GRAVITY_SOUTH;
context->gravity_hint = PANGO_GRAVITY_HINT_NATURAL;
-
+
context->language = NULL;
context->font_map = NULL;
pango_context_class_init (PangoContextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
+
object_class->finalize = pango_context_finalize;
}
pango_font_description_free (context->font_desc);
if (context->matrix)
pango_matrix_free (context->matrix);
-
+
G_OBJECT_CLASS (pango_context_parent_class)->finalize (object);
}
/**
* pango_context_new:
- *
+ *
* Creates a new #PangoContext initialized to default value.
*
* This function is only useful when implementing a new backend
* If you are using Pango as part of a higher-level system,
* that system may have it's own ways of create a #PangoContext.
* For instance, the GTK+ toolkit has, among others,
- * gdk_pango_context_get_for_screen(), and
+ * gdk_pango_context_get_for_screen(), and
* gtk_widget_get_pango_context().
- *
+ *
* Return value: the newly allocated #PangoContext, which should
* be freed with g_object_unref().
**/
PangoContext *context;
context = g_object_new (PANGO_TYPE_CONTEXT, NULL);
-
+
return context;
}
* @context: a #PangoContext
* @matrix: a #PangoMatrix, or %NULL to unset any existing matrix.
* (No matrix set is the same as setting the identity matrix.)
- *
+ *
* Sets the transformation matrix that will be applied when rendering
* with this context. Note that reported metrics are in the user space
* coordinates before the application of the matrix, not device-space
* pango_context_set_font_map:
* @context: a #PangoContext
* @font_map: the #PangoFontMap to set.
- *
+ *
* Sets the font map to be searched when fonts are looked-up in this context.
* This is only for internal use by Pango backends, a #PangoContext obtained
* via one of the recommended methods should already have a suitable font map.
/**
* pango_context_get_font_map:
* @context: a #PangoContext
- *
+ *
* Gets the #PangoFontmap used to look up fonts for this context.
- *
+ *
* Return value: the font map for the #PangoContext. This value
* is owned by Pango and should not be unreferenced.
*
* @families: location to store a pointer to an array of #PangoFontFamily *.
* This array should be freed with g_free().
* @n_families: location to store the number of elements in @descs
- *
+ *
* List all families for a context.
**/
void
if (n_families == NULL)
return;
-
+
if (context->font_map == NULL)
{
*n_families = 0;
if (families)
*families = NULL;
-
+
return;
}
- else
+ else
pango_font_map_list_families (context->font_map, families, n_families);
}
* pango_context_load_font:
* @context: a #PangoContext
* @desc: a #PangoFontDescription describing the font to load
- *
+ *
* Loads the font in one of the fontmaps in the context
* that is the closest match for @desc.
*
{
g_return_val_if_fail (context != NULL, NULL);
g_return_val_if_fail (pango_font_description_get_family (desc) != NULL, NULL);
-
+
return pango_font_map_load_font (context->font_map, context, desc);
}
* @context: a #PangoContext
* @desc: a #PangoFontDescription describing the fonts to load
* @language: a #PangoLanguage the fonts will be used for
- *
+ *
* Load a set of fonts in the context that can be used to render
* a font matching @desc.
*
* pango_context_set_font_description:
* @context: a #PangoContext
* @desc: the new pango font description
- *
+ *
* Set the default font description for the context
**/
void
/**
* pango_context_get_font_description:
* @context: a #PangoContext
- *
+ *
* Retrieve the default font description for the context.
- *
+ *
* Return value: a pointer to the context's default font description.
* This value must not be modified or freed.
**/
pango_context_get_font_description (PangoContext *context)
{
g_return_val_if_fail (context != NULL, NULL);
-
+
return context->font_desc;
}
* pango_context_set_language:
* @context: a #PangoContext
* @language: the new language tag.
- *
+ *
* Sets the global language tag for the context. The default language
* for the locale of the running process can be found using
* pango_language_get_default().
/**
* pango_context_get_language:
* @context: a #PangoContext
- *
+ *
* Retrieves the global language tag for the context.
- *
+ *
* Return value: the global language tag.
**/
PangoLanguage *
* pango_context_set_base_dir:
* @context: a #PangoContext
* @direction: the new base direction
- *
+ *
* Sets the base direction for the context.
*
* The base direction is used in applying the Unicode bidirectional
* %PANGO_DIRECTION_RTL, then the value will be used as the paragraph
* direction in the Unicode bidirectional algorithm. A value of
* %PANGO_DIRECTION_WEAK_LTR or %PANGO_DIRECTION_WEAK_RTL is used only
- * for paragraphs that do not contain any strong characters themselves.
+ * for paragraphs that do not contain any strong characters themselves.
**/
void
pango_context_set_base_dir (PangoContext *context,
/**
* pango_context_get_base_dir:
* @context: a #PangoContext
- *
+ *
* Retrieves the base direction for the context. See
* pango_context_set_base_dir().
- *
+ *
* Return value: the base direction for the context.
**/
PangoDirection
* pango_context_set_base_gravity:
* @context: a #PangoContext
* @gravity: the new base gravity
- *
+ *
* Sets the base gravity for the context.
*
* The base gravity is used in laying vertical text out.
/**
* pango_context_get_base_gravity:
* @context: a #PangoContext
- *
+ *
* Retrieves the base gravity for the context. See
* pango_context_set_base_gravity().
- *
+ *
* Return value: the base gravity for the context.
*
* Since: 1.16
/**
* pango_context_get_gravity:
* @context: a #PangoContext
- *
+ *
* Retrieves the gravity for the context. This is similar to
* pango_context_get_base_gravity(), except for when the base gravity
* is %PANGO_GRAVITY_AUTO for which pango_gravity_get_for_matrix() is used
* to return the gravity from the current context matrix.
- *
+ *
* Return value: the resolved gravity for the context.
*
* Since: 1.16
* pango_context_set_gravity_hint:
* @context: a #PangoContext
* @hint: the new gravity hint
- *
+ *
* Sets the gravity hint for the context.
*
* The gravity hint is used in laying vertical text out, and is only relevant
/**
* pango_context_get_gravity_hint:
* @context: a #PangoContext
- *
+ *
* Retrieves the gravity hint for the context. See
* pango_context_set_gravity_hint() for details.
- *
+ *
* Return value: the gravity hint for the context.
*
* Since: 1.16
int start_index)
{
int start_range, end_range;
-
+
pango_attr_iterator_range (iterator, &start_range, &end_range);
while (start_index >= end_range)
get_shaper_font_cache (PangoFontset *fontset)
{
ShaperFontCache *cache;
-
+
static GQuark cache_quark = 0;
if (!cache_quark)
cache_quark = g_quark_from_static_string ("pango-shaper-font-cache");
-
+
cache = g_object_get_qdata (G_OBJECT (fontset), cache_quark);
if (!cache)
{
PangoFont **font)
{
ShaperFontElement *element;
-
+
element = g_hash_table_lookup (cache->hash, GUINT_TO_POINTER (wc));
if (element)
{
ShaperFontElement *element = g_slice_new (ShaperFontElement);
element->shape_engine = shape_engine;
element->font = font;
-
+
g_hash_table_insert (cache->hash, GUINT_TO_POINTER (wc), element);
}
PangoContext *context;
const char *text;
const char *end;
-
+
const char *run_start;
const char *run_end;
gboolean copy_extra_attrs;
ChangedFlags changed;
-
+
PangoScriptIter *script_iter;
const char *script_end;
PangoScript script;
PangoLanguage *derived_lang;
PangoEngineLang *lang_engine;
-
+
PangoFontset *current_fonts;
ShaperFontCache *cache;
PangoFont *base_font;
gboolean enable_fallback;
-
+
GSList *exact_engines;
GSList *fallback_engines;
};
state->embedding_end_offset++;
state->embedding_end = g_utf8_next_char (state->embedding_end);
}
-
+
state->changed |= EMBEDDING_CHANGED;
}
PangoAttrType type)
{
GSList *node;
-
+
for (node = attr_list; node; node = node->next)
if (((PangoAttribute *) node->data)->klass->type == type)
return (PangoAttribute *) node->data;
PangoLanguage *old_lang;
PangoAttribute *attr;
int end_index;
-
+
pango_attr_iterator_range (state->attr_iter, NULL, &end_index);
if (end_index < state->end - state->text)
state->attr_end = state->text + end_index;
if (!state->lang)
state->lang = state->context->language;
-
+
attr = find_attribute (state->extra_attrs, PANGO_ATTR_FALLBACK);
state->enable_fallback = (attr == NULL || ((PangoAttrInt *)attr)->value);
static void
itemize_state_init (ItemizeState *state,
- PangoContext *context,
+ PangoContext *context,
const char *text,
PangoDirection base_dir,
int start_index,
state->item = NULL;
state->run_start = text + start_index;
-
+
/* First, apply the bidirectional algorithm to break
* the text into directional runs.
*/
state->embedding_levels = pango_log2vis_get_embedding_levels (text + start_index, length, &base_dir);
-
+
state->embedding_end_offset = 0;
state->embedding_end = text + start_index;
update_embedding_end (state);
state->lang = state->context->language;
state->extra_attrs = NULL;
state->copy_extra_attrs = FALSE;
-
+
state->attr_end = state->end;
state->enable_fallback = TRUE;
}
state->exact_engines = NULL;
state->fallback_engines = NULL;
state->base_font = NULL;
-
+
state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED;
}
{
GSList *new_list = NULL;
GSList *l;
-
+
for (l = attr_slist; l; l = l->next)
new_list = g_slist_prepend (new_list, pango_attribute_copy (l->data));
PangoFont *font)
{
GList *l;
-
+
for (l = state->result; l; l = l->next)
{
PangoItem *item = l->data;
if (font)
g_object_ref (font);
state->item->analysis.font = font;
-
+
state->item->analysis.level = state->embedding;
state->item->analysis.gravity = state->resolved_gravity;
state->item->analysis.flags = state->centered_baseline ? PANGO_ANALYSIS_FLAG_CENTERED_BASELINE : 0;
state->item->analysis.language = state->derived_lang;
-
+
if (state->copy_extra_attrs)
{
state->item->analysis.extra_attrs = copy_attr_slist (state->extra_attrs);
info.engines = state->exact_engines;
if (state->enable_fallback)
pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info);
- else
+ else
get_shaper_and_font_foreach (NULL, get_base_font (state), &info);
if (info.shape_engine)
info.engines = state->fallback_engines;
if (state->enable_fallback)
pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info);
- else
+ else
get_shaper_and_font_foreach (NULL, get_base_font (state), &info);
*shape_engine = info.shape_engine;
/* skip caching if fallback disabled (see above) */
if (state->enable_fallback)
shaper_font_cache_insert (state->cache, wc, *shape_engine, *font);
-
+
return *shape_engine != NULL;
}
PangoScript script)
{
PangoLanguage *derived_lang;
-
+
/* Make sure the language tag is consistent with the derived
* script. There is no point in marking up a section of
* Arabic text with the "en" language tag.
{
static guint engine_type_id = 0;
static guint render_type_id = 0;
-
+
if (engine_type_id == 0)
{
engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_LANG);
render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_NONE);
}
-
+
return pango_find_map (lang, engine_type_id, render_type_id);
}
if (old_derived_lang != state->derived_lang)
state->changed |= DERIVED_LANG_CHANGED;
}
-
+
if ((state->changed & DERIVED_LANG_CHANGED) || !state->lang_engine)
{
PangoMap *lang_map = get_lang_map (state->derived_lang);
if (state->changed & (SCRIPT_CHANGED | DERIVED_LANG_CHANGED))
itemize_state_reset_shape_engines (state);
-
+
if (state->changed & (FONT_CHANGED | DERIVED_LANG_CHANGED) &&
state->current_fonts)
{
{
get_shaper_and_font (state, wc, &shape_engine, &font);
}
-
+
itemize_state_add_character (state,
shape_engine, font,
is_forced_break || last_was_forced_break,
p);
-
+
last_was_forced_break = is_forced_break;
}
{
PangoEngineShape *shape_engine;
PangoFont *font;
-
+
if (!get_shaper_and_font (state, ' ', &shape_engine, &font))
{
shape_engine = _pango_get_fallback_shaper ();
* Since: 1.4
*/
GList *
-pango_itemize_with_base_dir (PangoContext *context,
+pango_itemize_with_base_dir (PangoContext *context,
PangoDirection base_dir,
const char *text,
int start_index,
itemize_state_init (&state, context, text, base_dir, start_index, length,
attrs, cached_iter, NULL);
-
- do
+
+ do
itemize_state_process_run (&state);
while (itemize_state_next (&state));
itemize_state_finish (&state);
-
+
return g_list_reverse (state.result);
}
static GList *
-itemize_with_font (PangoContext *context,
+itemize_with_font (PangoContext *context,
const char *text,
int start_index,
int length,
itemize_state_init (&state, context, text, context->base_dir, start_index, length,
NULL, NULL, desc);
- do
+ do
itemize_state_process_run (&state);
while (itemize_state_next (&state));
itemize_state_finish (&state);
-
+
return g_list_reverse (state.result);
}
* Return value: a #GList of #PangoItem structures.
*/
GList *
-pango_itemize (PangoContext *context,
+pango_itemize (PangoContext *context,
const char *text,
int start_index,
int length,
update_metrics_from_items (PangoFontMetrics *metrics,
PangoLanguage *language,
GList *items)
-
+
{
GHashTable *fonts_seen = g_hash_table_new (NULL, NULL);
int count = 0;
/* metrics will already be initialized from the first font in the fontset */
metrics->ascent = MAX (metrics->ascent, raw_metrics->ascent);
metrics->descent = MAX (metrics->descent, raw_metrics->descent);
-
+
if (count == 0)
{
metrics->approximate_char_width = raw_metrics->approximate_char_width;
metrics->approximate_digit_width = raw_metrics->approximate_digit_width;
}
else
- {
+ {
metrics->approximate_char_width += raw_metrics->approximate_char_width;
metrics->approximate_digit_width += raw_metrics->approximate_digit_width;
}
pango_font_metrics_unref (raw_metrics);
}
}
-
+
g_hash_table_destroy (fonts_seen);
-
+
if (count)
{
metrics->approximate_char_width /= count;
* large enough to cover a range of languages will be returned.
* The process of determining such metrics is slow, so it is best
* to always make sure some real language tag will be used.
- *
+ *
* Get overall metric information for a particular font
* description. Since the metrics may be substantially different for
* different scripts, a language tag can be provided to indicate that
PangoFontMetrics *metrics;
const char *sample_str;
GList *items;
-
+
g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
g_return_val_if_fail (desc != NULL, NULL);
current_fonts = pango_font_map_load_fontset (context->font_map, context, desc, language);
metrics = get_base_metrics (current_fonts);
-
+
sample_str = pango_language_get_sample_string (language);
items = itemize_with_font (context, sample_str, 0, strlen (sample_str), desc);
- update_metrics_from_items (metrics, language, items);
+ update_metrics_from_items (metrics, language, items);
g_list_foreach (items, (GFunc)pango_item_free, NULL);
g_list_free (items);
-
+
g_object_unref (current_fonts);
return metrics;
struct _PangoBlockInfo
{
- guchar *data;
+ guchar *data;
PangoCoverageLevel level; /* Used if data == NULL */
};
guint ref_count;
int n_blocks;
int data_size;
-
+
PangoBlockInfo *blocks;
};
/**
* pango_coverage_new:
- *
+ *
* Create a new #PangoCoverage
- *
+ *
* Return value: the newly allocated #PangoCoverage,
* initialized to %PANGO_COVERAGE_NONE
* with a reference count of one, which
coverage->n_blocks = N_BLOCKS_INCREMENT;
coverage->blocks = g_new0 (PangoBlockInfo, coverage->n_blocks);
coverage->ref_count = 1;
-
+
return coverage;
}
/**
* pango_coverage_copy:
* @coverage: a #PangoCoverage
- *
- * Copy an existing #PangoCoverage. (This function may now be unnecessary
+ *
+ * Copy an existing #PangoCoverage. (This function may now be unnecessary
* since we refcount the structure. File a bug if you use it.)
- *
+ *
* Return value: the newly allocated #PangoCoverage,
* with a reference count of one, which
* should be freed with pango_coverage_unref().
}
else
result->blocks[i].data = NULL;
-
+
result->blocks[i].level = coverage->blocks[i].level;
}
-
+
return result;
}
/**
* pango_coverage_ref:
* @coverage: a #PangoCoverage
- *
+ *
* Increase the reference count on the #PangoCoverage by one
*
* Return value: @coverage
/**
* pango_coverage_unref:
* @coverage: a #PangoCoverage
- *
+ *
* Increase the reference count on the #PangoCoverage by one.
* if the result is zero, free the coverage and all associated memory.
**/
pango_coverage_unref (PangoCoverage *coverage)
{
int i;
-
+
g_return_if_fail (coverage != NULL);
g_return_if_fail (coverage->ref_count > 0);
{
for (i=0; i<coverage->n_blocks; i++)
g_free (coverage->blocks[i].data);
-
+
g_free (coverage->blocks);
g_slice_free (PangoCoverage, coverage);
}
* pango_coverage_get:
* @coverage: a #PangoCoverage
* @index_: the index to check
- *
+ *
* Determine whether a particular index is covered by @coverage
- *
+ *
* Return value: the coverage level of @coverage for character @index_.
**/
PangoCoverageLevel
int index)
{
int block_index;
-
+
g_return_val_if_fail (coverage != NULL, PANGO_COVERAGE_NONE);
g_return_val_if_fail (index >= 0, PANGO_COVERAGE_NONE);
* @coverage: a #PangoCoverage
* @index_: the index to modify
* @level: the new level for @index_
- *
+ *
* Modify a particular index within @coverage
**/
void
{
int block_index, i;
guchar *data;
-
+
g_return_if_fail (coverage != NULL);
g_return_if_fail (index >= 0);
g_return_if_fail (level >= 0 && level <= 3);
coverage->n_blocks =
N_BLOCKS_INCREMENT * ((block_index + N_BLOCKS_INCREMENT) / N_BLOCKS_INCREMENT);
-
+
coverage->blocks = g_renew (PangoBlockInfo, coverage->blocks, coverage->n_blocks);
memset (coverage->blocks + old_n_blocks, 0,
sizeof (PangoBlockInfo) * (coverage->n_blocks - old_n_blocks));
if (!data)
{
guchar byte;
-
+
if (level == coverage->blocks[block_index].level)
return;
-
+
data = g_new (guchar, 64);
coverage->blocks[block_index].data = data;
(coverage->blocks[block_index].level << 2) |
(coverage->blocks[block_index].level << 4) |
(coverage->blocks[block_index].level << 6);
-
+
memset (data, byte, 64);
}
* pango_coverage_max:
* @coverage: a #PangoCoverage
* @other: another #PangoCoverage
- *
+ *
* Set the coverage for each index in @coverage to be the max (better)
* value of the current coverage for the index and the coverage for
* the corresponding index in @other.
{
int block_index, i;
int old_blocks;
-
+
g_return_if_fail (coverage != NULL);
-
+
old_blocks = MIN (coverage->n_blocks, other->n_blocks);
if (other->n_blocks > coverage->n_blocks)
{
coverage->n_blocks = other->n_blocks;
coverage->blocks = g_renew (PangoBlockInfo, coverage->blocks, coverage->n_blocks);
-
+
for (block_index = old_blocks; block_index < coverage->n_blocks; block_index++)
{
if (other->blocks[block_index].data)
}
else
coverage->blocks[block_index].data = NULL;
-
+
coverage->blocks[block_index].level = other->blocks[block_index].level;
}
}
-
+
for (block_index = 0; block_index < old_blocks; block_index++)
{
if (!coverage->blocks[block_index].data && !other->blocks[block_index].data)
else if (coverage->blocks[block_index].data && other->blocks[block_index].data)
{
guchar *data = coverage->blocks[block_index].data;
-
+
for (i=0; i<64; i++)
{
int byte1 = data[i];
coverage->blocks[block_index].data = dest;
level = coverage->blocks[block_index].level;
}
-
+
byte2 = level | (level << 2) | (level << 4) | (level << 6);
-
+
for (i=0; i<64; i++)
{
int byte1 = src[i];
* @coverage: a #PangoCoverage
* @bytes: location to store result (must be freed with g_free())
* @n_bytes: location to store size of result
- *
+ *
* Convert a #PangoCoverage structure into a flat binary format
**/
void
int size = 8 + 4 * coverage->n_blocks;
guchar *data;
int offset;
-
+
for (i=0; i<coverage->n_blocks; i++)
{
if (coverage->blocks[i].data)
*(guint32 *)&data[0] = g_htonl (PANGO_COVERAGE_MAGIC); /* Magic */
*(guint32 *)&data[4] = g_htonl (coverage->n_blocks);
offset = 8;
-
+
for (i=0; i<coverage->n_blocks; i++)
{
guint32 header_val;
{
guchar *data = coverage->blocks[i].data;
guchar first_val = data[0];
-
+
for (j = 1 ; j < 64; j++)
if (data[j] != first_val)
break;
* pango_coverage_from_bytes:
* @bytes: binary data representing a #PangoCoverage
* @n_bytes: the size of @bytes in bytes
- *
+ *
* Convert data generated from pango_converage_to_bytes() back
* to a #PangoCoverage
- *
+ *
* Return value: a newly allocated #PangoCoverage, or %NULL if
* the data was invalid.
**/
int i;
coverage->ref_count = 1;
-
+
if (n_bytes < 8)
goto error;
if (pango_coverage_get_uint32 (&ptr) != PANGO_COVERAGE_MAGIC)
goto error;
-
+
coverage->n_blocks = pango_coverage_get_uint32 (&ptr);
coverage->blocks = g_new0 (PangoBlockInfo, coverage->n_blocks);
for (i = 0; i < coverage->n_blocks; i++)
{
guint val;
-
+
if (ptr + 4 > bytes + n_bytes)
goto error;
{
if (ptr + 64 > bytes + n_bytes)
goto error;
-
+
coverage->blocks[i].data = g_new (guchar, 64);
memcpy (coverage->blocks[i].data, ptr, 64);
ptr += 64;
else
coverage->blocks[i].level = val;
}
-
+
return coverage;
error:
pango_coverage_unref (coverage);
return NULL;
}
-
+
PangoLanguage *language,
gunichar wc)
{
-
+
PangoCoverage *coverage = pango_font_get_coverage (font, language);
PangoCoverageLevel result = pango_coverage_get (coverage, wc);
typedef PangoEngineShape PangoFallbackEngine;
typedef PangoEngineShapeClass PangoFallbackEngineClass;
-static void
+static void
fallback_engine_shape (PangoEngineShape *engine,
PangoFont *font,
const char *text,
int n_chars;
int i;
const char *p;
-
+
n_chars = text ? g_utf8_strlen (text, length) : 0;
pango_glyph_string_set_size (glyphs, n_chars);
-
+
p = text;
for (i = 0; i < n_chars; i++)
{
PangoRectangle logical_rect;
PangoGlyph glyph = g_utf8_get_char (p) | PANGO_GLYPH_UNKNOWN_FLAG;
-
+
pango_font_get_glyph_extents (analysis->font, glyph, NULL, &logical_rect);
glyphs->glyphs[i].glyph = glyph;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->glyphs[i].geometry.width = logical_rect.width;
-
+
glyphs->log_clusters[i] = p - text;
p = g_utf8_next_char (p);
{
/*< private >*/
PangoEngineClass parent_class;
-
+
/*< public >*/
void (*script_break) (PangoEngineLang *engine,
const char *text,
{
/*< private >*/
PangoEngineClass parent_class;
-
+
/*< public >*/
void (*script_shape) (PangoEngineShape *engine,
PangoFont *font,
typedef struct _PangoEngineInfo PangoEngineInfo;
typedef struct _PangoEngineScriptInfo PangoEngineScriptInfo;
-struct _PangoEngineScriptInfo
+struct _PangoEngineScriptInfo
{
PangoScript script;
const gchar *langs;
* script_engine_list:
* @engines: location to store a pointer to an array of engines.
* @n_engines: location to store the number of elements in @engines.
- *
+ *
* Function to be provided by a module to list the engines that the
* module supplies. The function stores a pointer to an array
* of #PangoEngineInfo structures and the length of that array in
* script_engine_init:
* @module: a #GTypeModule structure used to associate any
* GObject types created in this module with the module.
- *
+ *
* Function to be provided by a module to register any
* GObject types in the module.
**/
/**
* script_engine_exit:
- *
+ *
* Function to be provided by the module that is called
* when the module is unloading. Frequently does nothing.
**/
/**
* script_engine_create:
* @id: the ID of an engine as reported by script_engine_list.
- *
+ *
* Function to be provided by the module to create an instance
* of one of the engines implemented by the module.
- *
+ *
* Return value: a newly created #PangoEngine of the specified
* type, or %NULL if an error occurred. (In normal operation,
* a module should not return %NULL. A %NULL return is only
struct _PangoFontMetrics
{
guint ref_count;
-
+
int ascent;
int descent;
int approximate_char_width;
GObjectClass parent_class;
/*< public >*/
-
+
void (*list_faces) (PangoFontFamily *family,
PangoFontFace ***faces,
int *n_faces);
PangoFontDescription *pango_font_face_describe (PangoFontFace *face);
G_CONST_RETURN char *pango_font_face_get_face_name (PangoFontFace *face);
-void pango_font_face_list_sizes (PangoFontFace *face,
- int **sizes,
+void pango_font_face_list_sizes (PangoFontFace *face,
+ int **sizes,
int *n_sizes);
#ifdef PANGO_ENABLE_BACKEND
GObjectClass parent_class;
/*< public >*/
-
+
const char * (*get_face_name) (PangoFontFace *face);
PangoFontDescription * (*describe) (PangoFontFace *face);
- void (*list_sizes) (PangoFontFace *face,
- int **sizes,
+ void (*list_sizes) (PangoFontFace *face,
+ int **sizes,
int *n_sizes);
/*< private >*/
GObjectClass parent_class;
/*< public >*/
-
+
PangoFontDescription *(*describe) (PangoFont *font);
PangoCoverage * (*get_coverage) (PangoFont *font,
PangoLanguage *lang);
* @fontmap: a #PangoFontMap
* @context: the #PangoContext the font will be used with
* @desc: a #PangoFontDescription describing the font to load
- *
+ *
* Load the font in the fontmap that is the closest match for @desc.
*
* Returns the font loaded, or %NULL if no font matched.
* @families: location to store a pointer to an array of #PangoFontFamily *.
* This array should be freed with g_free().
* @n_families: location to store the number of elements in @families
- *
- * List all families for a fontmap.
+ *
+ * List all families for a fontmap.
**/
void
pango_font_map_list_families (PangoFontMap *fontmap,
* @context: the #PangoContext the font will be used with
* @desc: a #PangoFontDescription describing the font to load
* @language: a #PangoLanguage the fonts will be used for
- *
+ *
* Load a set of fonts in the fontmap that can be used to render
* a font matching @desc.
*
{
g_return_val_if_fail (fontmap != NULL, NULL);
g_return_val_if_fail (pango_font_description_get_family (desc) != NULL, NULL);
-
+
return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_fontset (fontmap, context, desc, language);
}
pango_lookup_aliases (family,
&aliases,
&n_aliases);
-
+
if (n_aliases)
{
for (j = 0; j < n_aliases; j++)
families = g_strsplit (pango_font_description_get_family (desc), ",", -1);
fonts = pango_fontset_simple_new (language);
-
+
for (i = 0; families[i]; i++)
pango_font_map_fontset_add_fonts (fontmap,
context,
fonts,
tmp_desc,
families[i]);
-
+
g_strfreev (families);
/* The font description was completely unloadable, try with
if (pango_fontset_simple_size (fonts) == 0)
{
char *ctmp1, *ctmp2;
-
+
pango_font_description_set_family_static (tmp_desc,
pango_font_description_get_family (desc));
-
+
ctmp1 = pango_font_description_to_string (desc);
pango_font_description_set_family_static (tmp_desc, "Sans");
g_free (ctmp2);
}
g_free (ctmp1);
-
+
pango_font_map_fontset_add_fonts (fontmap,
context,
fonts,
tmp_desc,
"Sans");
}
-
+
/* We couldn't try with Sans and the specified style. Try Sans Normal
*/
if (pango_fontset_simple_size (fonts) == 0)
{
char *ctmp1, *ctmp2;
-
+
pango_font_description_set_family_static (tmp_desc, "Sans");
ctmp1 = pango_font_description_to_string (tmp_desc);
pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL);
g_hash_table_insert (warned_fonts, g_strdup (ctmp1), GINT_TO_POINTER (1));
ctmp2 = pango_font_description_to_string (tmp_desc);
-
+
g_warning ("couldn't load font \"%s\", falling back to \"%s\", "
"expect ugly output.", ctmp1, ctmp2);
g_free (ctmp2);
}
g_free (ctmp1);
-
+
pango_font_map_fontset_add_fonts (fontmap,
context,
fonts,
/**
* pango_font_map_get_shape_engine_type:
* @fontmap: a #PangoFontMap
- *
+ *
* Returns the render ID for shape engines for this fontmap.
* See the <structfield>render_type</structfield> field of
* #PangoEngineInfo.
- *
+ *
* Return value: the ID string for shape engines for
* this fontmap. Owned by Pango, should not be modified
* or freed.
pango_font_map_get_shape_engine_type (PangoFontMap *fontmap)
{
g_return_val_if_fail (PANGO_IS_FONT_MAP (fontmap), NULL);
-
+
return PANGO_FONT_MAP_GET_CLASS (fontmap)->shape_engine_type;
}
GObjectClass parent_class;
/*< public >*/
-
+
PangoFont * (*load_font) (PangoFontMap *fontmap,
PangoContext *context,
const PangoFontDescription *desc);
PangoContext *context,
const PangoFontDescription *desc,
PangoLanguage *language);
-
+
const char *shape_engine_type;
/*< private >*/
pango_fontset_get_font (PangoFontset *fontset,
guint wc)
{
-
+
g_return_val_if_fail (PANGO_IS_FONTSET (fontset), NULL);
return PANGO_FONTSET_GET_CLASS (fontset)->get_font (fontset, wc);
/**
* pango_fontset_get_metrics:
* @fontset: a #PangoFontset
- *
+ *
* Get overall metric information for the fonts in the fontset.
*
* Return value: a #PangoFontMetrics object. The caller must call pango_font_metrics_unref()
* @fontset: a #PangoFontset
* @func: Callback function
* @data: data to pass to the callback function
- *
+ *
* Iterates through all the fonts in a fontset, calling @func for
* each one. If @func returns %TRUE, that stops the iteration.
*
{
raw_metrics = pango_font_get_metrics (font, language);
g_hash_table_insert (fonts_seen, font, font);
-
+
if (count == 0)
{
metrics->ascent = raw_metrics->ascent;
metrics->approximate_digit_width = raw_metrics->approximate_digit_width;
}
else
- {
+ {
metrics->ascent = MAX (metrics->ascent, raw_metrics->ascent);
metrics->descent = MAX (metrics->descent, raw_metrics->descent);
metrics->approximate_char_width += raw_metrics->approximate_char_width;
else
g_object_unref (font);
}
-
+
p = g_utf8_next_char (p);
}
g_hash_table_destroy (fonts_seen);
-
+
if (count)
{
metrics->approximate_char_width /= count;
/**
* pango_fontset_simple_new:
* @language: a #PangoLanguage tag
- *
+ *
* Creates a new #PangoFontsetSimple for the given language.
*
* Return value: the newly allocated #PangoFontsetSimple, which should
pango_fontset_simple_new (PangoLanguage *language)
{
PangoFontsetSimple *fontset;
-
+
fontset = g_object_new (PANGO_TYPE_FONTSET_SIMPLE, NULL);
fontset->language = language;
-
+
return fontset;
}
PangoFontsetClass *fontset_class = PANGO_FONTSET_CLASS (class);
simple_parent_class = g_type_class_peek_parent (class);
-
+
object_class->finalize = pango_fontset_simple_finalize;
fontset_class->get_font = pango_fontset_simple_get_font;
fontset_class->get_metrics = pango_fontset_simple_get_metrics;
fontset_class->foreach = pango_fontset_simple_foreach;
}
-static void
+static void
pango_fontset_simple_init (PangoFontsetSimple *fontset)
{
fontset->fonts = g_ptr_array_new ();
if (coverage)
pango_coverage_unref (coverage);
}
-
+
g_ptr_array_free (fontset->coverages, TRUE);
G_OBJECT_CLASS (simple_parent_class)->finalize (object);
* pango_fontset_simple_size:
* @fontset: a #PangoFontsetSimple.
*
- * Returns the number of fonts in the fontset.
+ * Returns the number of fonts in the fontset.
*
* Return value: the size of @fontset.
**/
pango_fontset_simple_get_metrics (PangoFontset *fontset)
{
PangoFontsetSimple *simple = PANGO_FONTSET_SIMPLE (fontset);
-
+
if (simple->fonts->len == 1)
return pango_font_get_metrics (PANGO_FONT (g_ptr_array_index(simple->fonts, 0)),
simple->language);
-
+
return PANGO_FONTSET_CLASS (simple_parent_class)->get_metrics (fontset);
}
PangoCoverage *coverage;
int result = -1;
unsigned int i;
-
+
for (i = 0; i < simple->fonts->len; i++)
{
coverage = g_ptr_array_index (simple->coverages, i);
-
+
if (coverage == NULL)
{
font = g_ptr_array_index (simple->fonts, i);
-
+
coverage = pango_font_get_coverage (font, simple->language);
g_ptr_array_index (simple->coverages, i) = coverage;
}
-
+
level = pango_coverage_get (coverage, wc);
-
+
if (result == -1 || level > best_level)
{
result = i;
{
PangoFontsetSimple *simple = PANGO_FONTSET_SIMPLE (fontset);
unsigned int i;
-
+
for (i = 0; i < simple->fonts->len; i++)
{
if ((*func) (fontset,
* @fontset: a #PangoFontset
* @font: a font from @fontset
* @data: callback data
- *
+ *
* A callback function used by pango_fontset_foreach() when enumerating
* the fonts in a fontset.
*
GObjectClass parent_class;
/*< public >*/
-
+
PangoFont * (*get_font) (PangoFontset *fontset,
guint wc);
{
PangoGlyphItem *glyph_item;
const gchar *text;
-
+
int start_glyph;
int start_index;
int start_char;
* @orig: a #PangoItem
* @text: text to which positions in @orig apply
* @split_index: byte index of position to split item, relative to the start of the item
- *
+ *
* Modifies @orig to cover only the text after @split_index, and
* returns a new item that covers the text before @split_index that
* used to be in @orig. You can think of @split_index as the length of
*
* This function is similar in function to pango_item_split() (and uses
* it internally.)
- *
+ *
* Return value: the newly allocated item representing text before
* @split_index, which should be freed
* with pango_glyph_item_free().
{
memcpy (new->glyphs->glyphs, orig->glyphs->glyphs, num_glyphs * sizeof (PangoGlyphInfo));
memcpy (new->glyphs->log_clusters, orig->glyphs->log_clusters, num_glyphs * sizeof (int));
-
+
memmove (orig->glyphs->glyphs, orig->glyphs->glyphs + num_glyphs,
num_remaining * sizeof (PangoGlyphInfo));
for (i = num_glyphs; i < orig->glyphs->num_glyphs; i++)
/**
* pango_glyph_item_free:
* @glyph_item: a #PangoGlyphItem
- *
+ *
* Frees a #PangoGlyphItem and memory to which it points.
*
* Since: 1.6
/**
* _pango_glyph_item_iter_next_cluster:
* @iter: a #PangoGlyphItemIter
- *
+ *
* Advances the iterator to the next cluster in the glyph item.
- *
+ *
* Return value: %TRUE if the iterator was advanced, %FALSE if we were already on the
* last cluster.
**/
if (glyph_index < 0)
return FALSE;
}
-
+
iter->start_glyph = iter->end_glyph;
iter->start_index = iter->end_index;
iter->start_char = iter->end_char;
-
+
if (LTR (iter->glyph_item))
{
cluster = glyphs->log_clusters[glyph_index + 1];
while (TRUE)
{
glyph_index++;
-
+
if (glyph_index == glyphs->num_glyphs)
{
iter->end_index = item->offset + item->length;
iter->end_char = item->num_chars;
break;
}
-
+
if (glyphs->log_clusters[glyph_index] != cluster)
{
iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
iter->end_index - iter->start_index);
- break;
+ break;
}
}
}
while (TRUE)
{
glyph_index--;
-
+
if (glyph_index < 0)
{
iter->end_index = item->offset + item->length;
iter->end_char = item->num_chars;
break;
}
-
+
if (glyphs->log_clusters[glyph_index] != cluster)
{
iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
iter->end_index - iter->start_index);
- break;
+ break;
}
}
}
/**
* _pango_glyph_item_iter_prev_cluster:
* @iter: a #PangoGlyphItemIter
- *
+ *
* Moves the iterator to the preceding cluster in the glyph item.
- *
+ *
* Return value: %TRUE if the iterator was moved, %FALSE if we were already on the
* first cluster.
**/
PangoGlyphString *glyphs = iter->glyph_item->glyphs;
int cluster;
PangoItem *item = iter->glyph_item->item;
-
+
if (LTR (iter->glyph_item))
{
if (glyph_index == 0)
{
if (glyph_index == glyphs->num_glyphs - 1)
return FALSE;
-
+
}
-
+
iter->end_glyph = iter->start_glyph;
iter->end_index = iter->start_index;
iter->end_char = iter->start_char;
-
+
if (LTR (iter->glyph_item))
{
cluster = glyphs->log_clusters[glyph_index - 1];
while (TRUE)
{
glyph_index--;
-
+
if (glyph_index == 0)
{
iter->start_index = item->offset;
iter->start_char = 0;
break;
}
-
+
if (glyphs->log_clusters[glyph_index] != cluster)
{
iter->start_index = item->offset + glyphs->log_clusters[glyph_index];
iter->start_char -= g_utf8_strlen (iter->text + iter->start_index,
iter->end_index - iter->start_index);
- break;
+ break;
}
}
}
while (TRUE)
{
glyph_index++;
-
+
if (glyph_index == glyphs->num_glyphs - 1)
{
iter->start_index = item->offset;
iter->start_char = 0;
break;
}
-
+
if (glyphs->log_clusters[glyph_index] != cluster)
{
iter->start_index = item->offset + glyphs->log_clusters[glyph_index];
iter->start_char -= g_utf8_strlen (iter->text + iter->start_index,
iter->end_index - iter->start_index);
- break;
+ break;
}
}
}
* @iter: pointer to a #PangoGlyphItemIter structure
* @glyph_item: the glyph item that @iter points into
* @text: text corresponding to the glyph item
- *
+ *
* Initializes a #PangoGlyphItemIter structure to point to the
* first cluster in a glyph item.
- *
+ *
* Return value: %FALSE if there are no clusters in the glyph item;
* in this case, the state of @iter is undefined.
**/
{
iter->glyph_item = glyph_item;
iter->text = text;
-
+
if (LTR (glyph_item))
iter->end_glyph = 0;
else
* @iter: pointer to a #PangoGlyphItemIter structure
* @glyph_item: the glyph item that @iter points into
* @text: text corresponding to the glyph item
- *
+ *
* Initializes a #PangoGlyphItemIter structure to point to the
* last cluster in a glyph item.
- *
+ *
* Return value: %FALSE if there are no clusters in the glyph item;
* in this case, the state of @iter is undefined.
**/
{
iter->glyph_item = glyph_item;
iter->text = text;
-
+
if (LTR (glyph_item))
iter->start_glyph = glyph_item->glyphs->num_glyphs;
else
return _pango_glyph_item_iter_prev_cluster (iter);
}
-typedef struct
+typedef struct
{
PangoGlyphItemIter iter;
-
+
GSList *segment_attrs;
} ApplyAttrsState;
{
GSList *tmp_list;
GSList *new_attrs;
-
+
new_attrs = g_slist_copy (attrs);
-
+
for (tmp_list = new_attrs; tmp_list; tmp_list = tmp_list->next)
tmp_list->data = pango_attribute_copy (tmp_list->data);
state->iter.start_glyph -= split_item->glyphs->num_glyphs;
state->iter.end_glyph -= split_item->glyphs->num_glyphs;
}
-
+
state->iter.start_char -= split_item->item->num_chars;
state->iter.end_char -= split_item->item->num_chars;
-
+
return split_item;
}
/**
* pango_glyph_item_apply_attrs:
- * @glyph_item: a shaped item
+ * @glyph_item: a shaped item
* @text: text that @list applies to
* @list: a #PangoAttrList
- *
+ *
* Splits a shaped item (PangoGlyphItem) into multiple items based
* on an attribute list. The idea is that if you have attributes
* that don't affect shaping, such as color or underline, to avoid
*
* This function takes ownership of @glyph_item; it will be reused
* as one of the elements in the list.
- *
+ *
* Return value: a list of glyph items resulting from splitting
* @glyph_item. Free the elements using pango_glyph_item_free(),
* the list using g_slist_free().
while (pango_attr_iterator_next (iter));
state.segment_attrs = pango_attr_iterator_get_attrs (iter);
-
+
/* Short circuit the case when we don't actually need to
* split the item
*/
have_cluster = _pango_glyph_item_iter_next_cluster (&state.iter))
{
gboolean have_next;
-
+
/* [range_start,range_end] is the first range that intersects
* the current cluster.
*/
split_before_cluster_start (&state));
state.segment_attrs = pango_attr_iterator_get_attrs (iter);
}
-
+
start_new_segment = FALSE;
/* Loop over all ranges that intersect this cluster; exiting
state.iter.start_index != glyph_item->item->offset)
{
GSList *new_attrs = attr_slist_copy (state.segment_attrs);
- result = g_slist_prepend (result,
+ result = g_slist_prepend (result,
split_before_cluster_start (&state));
state.segment_attrs = new_attrs;
}
-
+
state.segment_attrs = g_slist_concat (state.segment_attrs,
pango_attr_iterator_get_attrs (iter));
}
result = g_slist_reverse (result);
pango_attr_iterator_destroy (iter);
-
+
return result;
}
* @letter_spacing: amount of letter spacing to add
* in Pango units. May be negative, though too large
* negative values will give ugly results.
- *
+ *
* Adds spacing between the graphemes of @glyph_item to
* give the effect of typographic letter spacing.
*
struct _PangoGlyphGeometry
{
PangoGlyphUnit width;
- PangoGlyphUnit x_offset;
+ PangoGlyphUnit x_offset;
PangoGlyphUnit y_offset;
};
guint is_cluster_start : 1;
};
-/* A single glyph
+/* A single glyph
*/
struct _PangoGlyphInfo
{
{
PangoScriptProperties props = get_script_properties (script);
gboolean vertical;
-
+
if (G_UNLIKELY (base_gravity == PANGO_GRAVITY_AUTO))
base_gravity = props.preferred_gravity;
-
+
vertical = PANGO_GRAVITY_IS_VERTICAL (base_gravity);
/* Everything is designed such that a system with no vertical support
* @PANGO_GRAVITY_NORTH: Glyphs are upside-down
* @PANGO_GRAVITY_WEST: Glyphs are rotated 90 degrees counter-clockwise
* @PANGO_GRAVITY_AUTO: Gravity is resolved from the context matrix
- *
+ *
* The #PangoGravity type represents the orientation of glyphs in a segment
* of text. This is useful when rendering vertical text layouts. In
* those situations, the layout is rotated using a non-identity PangoMatrix,
* pango_context_get_base_gravity().
*
* See also: #PangoGravityHint
- *
+ *
* Since: 1.16
- **/
+ **/
typedef enum {
PANGO_GRAVITY_SOUTH,
PANGO_GRAVITY_EAST,
* Latin in East gravity), choose per-script gravity such that every script
* respects the line progression. This means, Latin and Arabic will take
* opposite gravities and both flow top-to-bottom for example.
- *
+ *
* The #PangoGravityHint defines how horizontal scripts should behave in a
* vertical context. That is, English excerpt in a vertical paragraph for
* example.
typedef struct _PangoWarningHistory PangoWarningHistory;
struct _PangoWarningHistory {
- guint shape_font : 1;
+ guint shape_font : 1;
guint shape_shape_engine : 1;
guint get_glyph_extents : 1;
guint get_metrics : 1;
guint get_font_map : 1;
-};
+};
extern PangoWarningHistory _pango_warning_history;
/**
* pango_item_new:
- *
+ *
* Creates a new #PangoItem structure initialized to default values.
- *
+ *
* Return value: the newly allocated #PangoItem, which should
* be freed with pango_item_free().
**/
/**
* pango_item_copy:
* @item: a #PangoItem
- *
+ *
* Copy an existing #PangoItem structure.
- *
+ *
* Return value: the newly allocated #PangoItem, which should
* be freed with pango_item_free().
**/
result->analysis = item->analysis;
if (result->analysis.font)
g_object_ref (result->analysis.font);
-
+
extra_attrs = NULL;
tmp_list = item->analysis.extra_attrs;
while (tmp_list)
/**
* pango_item_free:
* @item: a #PangoItem
- *
+ *
* Free a #PangoItem and all associated memory.
**/
void
pango_item_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoItem"),
(GBoxedCopyFunc) pango_item_copy,
* @orig: a #PangoItem
* @split_index: byte index of position to split item, relative to the start of the item
* @split_offset: number of chars between start of @orig and @split_index
- *
+ *
* Modifies @orig to cover only the text after @split_index, and
* returns a new item that covers the text before @split_index that
* used to be in @orig. You can think of @split_index as the length of
* chars, and must be provided because the text used to generate the
* item isn't available, so pango_item_split() can't count the char
* length of the split items itself.
- *
+ *
* Return value: new item representing text before @split_index, which
* should be freed with pango_item_free().
**/
g_return_val_if_fail (split_index < orig->length, NULL);
g_return_val_if_fail (split_offset > 0, NULL);
g_return_val_if_fail (split_offset < orig->num_chars, NULL);
-
+
new_item = pango_item_copy (orig);
new_item->length = split_index;
new_item->num_chars = split_offset;
-
+
orig->offset += split_index;
orig->length -= split_index;
orig->num_chars -= split_offset;
-
+
return new_item;
}
/* If you add fields to PangoLayout, be sure to update both
* the _copy function
*/
-
+
PangoContext *context;
PangoAttrList *attrs;
PangoFontDescription *font_desc;
-
+
gchar *text;
int length; /* length of text in bytes */
int width; /* wrap width, in device units */
guint single_paragraph : 1;
guint auto_dir : 1;
-
+
guint wrap : 2; /* PangoWrapMode */
guint is_wrapped : 1; /* Whether the layout has any wrapped lines */
guint ellipsize : 2; /* PangoEllipsizeMode */
int tab_width; /* Cached width of a tab. -1 == not yet calculated */
PangoTabArray *tabs;
-
+
GSList *lines;
};
{
/* Vertical position of the line's baseline in layout coords */
int baseline;
-
+
/* Line extents in layout coords */
PangoRectangle ink_rect;
PangoRectangle logical_rect;
/* list of Extents for each line in layout coordinates */
GSList *line_extents;
GSList *line_extents_link;
-
+
/* X position of the current run */
int run_x;
pango_layout_class_init (PangoLayoutClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
+
object_class->finalize = pango_layout_finalize;
}
layout = PANGO_LAYOUT (object);
pango_layout_clear_lines (layout);
-
+
if (layout->context)
g_object_unref (layout->context);
-
+
if (layout->attrs)
pango_attr_list_unref (layout->attrs);
if (layout->tabs)
pango_tab_array_free (layout->tabs);
-
+
G_OBJECT_CLASS (pango_layout_parent_class)->finalize (object);
}
/**
* pango_layout_new:
* @context: a #PangoContext
- *
+ *
* Create a new #PangoLayout object with attributes initialized to
* default values for a particular #PangoContext.
- *
+ *
* Return value: the newly allocated #PangoLayout, with a reference
* count of one, which should be freed with
* g_object_unref().
/**
* pango_layout_copy:
* @src: a #PangoLayout
- *
+ *
* Does a deep copy-by-value of the @src layout. The attribute list,
* tab array, and text from the original layout are all copied by
* value.
- *
+ *
* Return value: the newly allocated #PangoLayout, with a reference
* count of one, which should be freed with
* g_object_unref().
pango_layout_copy (PangoLayout *src)
{
PangoLayout *layout;
-
+
g_return_val_if_fail (PANGO_IS_LAYOUT (src), NULL);
layout = pango_layout_new (src->context);
if (src->tabs)
layout->tabs = pango_tab_array_copy (src->tabs);
- layout->wrap = src->wrap;
+ layout->wrap = src->wrap;
layout->ellipsize = src->ellipsize;
layout->unknown_glyphs_count = -1;
-
+
/* unknown_glyphs_count, is_wrapped, is_ellipsized, log_attrs, lines
* fields are updated by check_lines */
/**
* pango_layout_get_context:
* @layout: a #PangoLayout
- *
+ *
* Retrieves the #PangoContext used for this layout.
- *
+ *
* Return value: the #PangoContext for the layout. This does not
* have an additional refcount added, so if you want to keep
* a copy of this around, you must reference it yourself.
* @layout: a #PangoLayout.
* @width: the desired width in Pango units, or -1 to indicate that no
* wrapping should be performed.
- *
+ *
* Sets the width to which the lines of the #PangoLayout should wrap.
**/
void
/**
* pango_layout_get_width:
* @layout: a #PangoLayout
- *
+ *
* Gets the width to which the lines of the #PangoLayout should wrap.
- *
+ *
* Return value: the width, or -1 if no width set.
**/
int
* pango_layout_set_wrap:
* @layout: a #PangoLayout
* @wrap: the wrap mode
- *
+ *
* Sets the wrap mode; the wrap mode only has effect if a width
* is set on the layout with pango_layout_set_width(). To turn off wrapping,
* set the width to -1.
/**
* pango_layout_get_wrap:
* @layout: a #PangoLayout
- *
+ *
* Gets the wrap mode for the layout.
*
* Use pango_layout_is_wrapped() to query whether any paragraphs
* were actually wrapped.
- *
+ *
* Return value: active wrap mode.
**/
PangoWrapMode
pango_layout_get_wrap (PangoLayout *layout)
{
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), 0);
-
+
return layout->wrap;
}
/**
* pango_layout_is_wrapped:
* @layout: a #PangoLayout
- *
+ *
* Queries whether the layout had to wrap any paragraphs.
*
* This returns %TRUE if a positive width is set on @layout,
* pango_layout_set_indent
* @layout: a #PangoLayout.
* @indent: the amount by which to indent.
- *
+ *
* Sets the width in Pango units to indent each paragraph. A negative value
* of @indent will produce a hanging indentation. That is, the first line will
* have the full width, and subsequent lines will be indented by the
/**
* pango_layout_get_indent:
* @layout: a #PangoLayout
- *
+ *
* Gets the paragraph indent width in Pango units. A negative value
* indicates a hanging indentation.
- *
+ *
* Return value: the indent.
**/
int
* pango_layout_set_spacing:
* @layout: a #PangoLayout.
* @spacing: the amount of spacing
- *
+ *
* Sets the amount of spacing in #PangoGlyphUnit between the lines of the
* layout.
*
/**
* pango_layout_get_spacing:
* @layout: a #PangoLayout
- *
+ *
* Gets the amount of spacing in #PangoGlyphUnit between the lines of the
* layout.
- *
+ *
* Return value: the spacing.
**/
int
* pango_layout_set_attributes:
* @layout: a #PangoLayout
* @attrs: a #PangoAttrList
- *
+ *
* Sets the text attributes for a layout object.
**/
void
/**
* pango_layout_get_attributes:
* @layout: a #PangoLayout
- *
+ *
* Gets the attribute list for the layout, if any.
- *
+ *
* Return value: a #PangoAttrList.
**/
PangoAttrList*
* @layout: a #PangoLayout
* @desc: the new #PangoFontDescription, or %NULL to unset the
* current font description
- *
- * Sets the default font description for the layout. If no font
+ *
+ * Sets the default font description for the layout. If no font
* description is set on the layout, the font description from
* the layout's context is used.
**/
{
if (layout->font_desc)
pango_font_description_free (layout->font_desc);
-
+
if (desc)
layout->font_desc = pango_font_description_copy (desc);
else
layout->font_desc = NULL;
-
+
pango_layout_clear_lines (layout);
layout->tab_width = -1;
}
/**
* pango_layout_get_font_description:
* @layout: a #PangoLayout
- *
+ *
* Gets the font description for the layout, if any.
- *
+ *
* Return value: a pointer to the layout's font description,
* or %NULL if the font description from the layout's
* context is inherited. This value is owned by the layout
* pango_layout_set_justify:
* @layout: a #PangoLayout
* @justify: whether the lines in the layout should be justified.
- *
+ *
* Sets whether each complete line should be stretched to
* fill the entire width of the layout. This stretching is typically
* done by adding whitespace, but for some scripts (such as Arabic),
/**
* pango_layout_get_justify:
* @layout: a #PangoLayout
- *
+ *
* Gets whether each complete line should be stretched to fill the entire
* width of the layout.
- *
+ *
* Return value: the justify.
**/
gboolean
* @layout: a #PangoLayout
* @auto_dir: if %TRUE, compute the bidirectional base direction
* from the layout's contents.
- *
+ *
* Sets whether to calculate the bidirectional base direction
* for the layout according to the contents of the layout;
* when this flag is on (the default), then paragraphs in
*
* When the auto-computed direction of a paragraph differs from the
* base direction of the context, the interpretation of
- * %PANGO_ALIGN_LEFT and %PANGO_ALIGN_RIGHT are swapped.
+ * %PANGO_ALIGN_LEFT and %PANGO_ALIGN_RIGHT are swapped.
*
* Since: 1.4
**/
/**
* pango_layout_get_auto_dir:
* @layout: a #PangoLayout
- *
+ *
* Gets whether to calculate the bidirectional base direction
* for the layout according to the contents of the layout.
* See pango_layout_set_auto_dir().
- *
+ *
* Return value: %TRUE if the bidirectional base direction
* is computed from the layout's contents, %FALSE otherwise.
*
pango_layout_get_auto_dir (PangoLayout *layout)
{
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), FALSE);
-
+
return layout->auto_dir;
}
* pango_layout_set_alignment:
* @layout: a #PangoLayout
* @alignment: the alignment
- *
+ *
* Sets the alignment for the layout: how partial lines are
* positioned within the horizontal space available.
**/
/**
* pango_layout_get_alignment:
* @layout: a #PangoLayout
- *
+ *
* Gets the alignment for the layout: how partial lines are
* positioned within the horizontal space available.
- *
+ *
* Return value: the alignment.
**/
PangoAlignment
/**
* pango_layout_set_tabs:
- * @layout: a #PangoLayout
+ * @layout: a #PangoLayout
* @tabs: a #PangoTabArray
- *
+ *
* Sets the tabs to use for @layout, overriding the default tabs
* (by default, tabs are every 8 spaces). If @tabs is %NULL, the default
* tabs are reinstated. @tabs is copied into the layout; you must
PangoTabArray *tabs)
{
g_return_if_fail (PANGO_IS_LAYOUT (layout));
-
+
if (layout->tabs)
pango_tab_array_free (layout->tabs);
/**
* pango_layout_get_tabs:
* @layout: a #PangoLayout
- *
+ *
* Gets the current #PangoTabArray used by this layout. If no
* #PangoTabArray has been set, then the default tabs are in use
* and %NULL is returned. Default tabs are every 8 spaces.
* The return value should be freed with pango_tab_array_free().
- *
+ *
* Return value: a copy of the tabs for this layout, or %NULL.
**/
PangoTabArray*
* pango_layout_set_single_paragraph_mode:
* @layout: a #PangoLayout
* @setting: new setting
- *
+ *
* If @setting is %TRUE, do not treat newlines and similar characters
* as paragraph separators; instead, keep all text in a single paragraph,
* and display a glyph for paragraph separator characters. Used when
* you want to allow editing of newlines on a single text line.
- *
+ *
**/
void
pango_layout_set_single_paragraph_mode (PangoLayout *layout,
/**
* pango_layout_get_single_paragraph_mode:
* @layout: a #PangoLayout
- *
+ *
* Obtains the value set by pango_layout_set_single_paragraph_mode().
- *
- * Return value: %TRUE if the layout does not break paragraphs at
+ *
+ * Return value: %TRUE if the layout does not break paragraphs at
* paragraph separator characters, %FALSE otherwise.
**/
gboolean
* pango_layout_set_ellipsize:
* @layout: a #PangoLayout
* @ellipsize: the new ellipsization mode for @layout
- *
+ *
* Sets the type of ellipsization being performed for @layout.
* Depending on the ellipsization mode @ellipsize text is
* removed from the start, middle, or end of lines so they
if (ellipsize != layout->ellipsize)
{
layout->ellipsize = ellipsize;
-
+
pango_layout_clear_lines (layout);
}
}
/**
* pango_layout_get_ellipsize:
* @layout: a #PangoLayout
- *
+ *
* Gets the type of ellipsization being performed for @layout.
* See pango_layout_set_ellipsize()
- *
+ *
* Return value: the current ellipsization mode for @layout.
*
* Use pango_layout_is_ellipsized() to query whether any paragraphs
* were actually ellipsized.
- *
+ *
* Since: 1.6
**/
PangoEllipsizeMode
/**
* pango_layout_is_ellipsized:
* @layout: a #PangoLayout
- *
+ *
* Queries whether the layout had to ellipsize any paragraphs.
*
* This returns %TRUE if the ellipsization mode for @layout
* calculated. The text will also be truncated on
* encountering a nul-termination even when @length is
* positive.
- *
+ *
* Sets the text of the layout.
**/
void
int length)
{
char *old_text, *start, *end;
-
+
g_return_if_fail (layout != NULL);
g_return_if_fail (length == 0 || text != NULL);
old_text = layout->text;
-
+
if (length < 0)
layout->text = g_strdup (text);
else if (length > 0)
start = layout->text;
for (;;) {
gboolean valid;
-
+
valid = g_utf8_validate (start, -1, (const char **)&end);
if (!*end)
layout->n_chars = g_utf8_strlen (layout->text, -1);
pango_layout_clear_lines (layout);
-
+
g_free (old_text);
}
/**
* pango_layout_get_text:
* @layout: a #PangoLayout
- *
+ *
* Gets the text in the layout. The returned text should not
* be freed or modified.
- *
+ *
* Return value: the text in the @layout.
**/
G_CONST_RETURN char*
*
* Same as pango_layout_set_markup_with_accel(), but
* the markup text isn't scanned for accelerators.
- *
+ *
**/
void
pango_layout_set_markup (PangoLayout *layout,
/**
* pango_layout_set_markup_with_accel:
* @layout: a #PangoLayout
- * @markup: marked-up text
+ * @markup: marked-up text
* (see <link linkend="PangoMarkupFormat">markup format</link>)
* @length: length of marked-up text in bytes, or -1 if @markup is
* nul-terminated
* @accel_marker: marker for accelerators in the text
* @accel_char: return location for first located accelerator, or %NULL
- *
+ *
* Sets the layout text and attribute list from marked-up text (see
* <link linkend="PangoMarkupFormat">markup format</link>). Replaces
* the current text and attribute list.
PangoAttrList *list = NULL;
char *text = NULL;
GError *error;
-
+
g_return_if_fail (PANGO_IS_LAYOUT (layout));
g_return_if_fail (markup != NULL);
-
+
error = NULL;
if (!pango_parse_markup (markup, length,
accel_marker,
g_error_free (error);
return;
}
-
+
pango_layout_set_text (layout, text, -1);
pango_layout_set_attributes (layout, list);
pango_attr_list_unref (list);
/**
* pango_layout_get_unknown_glyphs_count:
* @layout: a #PangoLayout
- *
+ *
* Counts the number unknown glyphs in @layout. That is, zero if
* glyphs for all characters in the layout text were found, or more
* than zero otherwise.
/**
* pango_layout_context_changed:
* @layout: a #PangoLayout
- *
+ *
* Forces recomputation of any state in the #PangoLayout that
* might depend on the layout's context. This function should
* be called if you make changes to the context subsequent
* of characters in the layout, since there need to be attributes
* corresponding to both the position before the first character
* and the position after the last character.)
- *
+ *
* Retrieves an array of logical attributes for each character in
- * the @layout.
+ * the @layout.
**/
void
pango_layout_get_log_attrs (PangoLayout *layout,
*attrs = g_new (PangoLogAttr, layout->n_chars + 1);
memcpy (*attrs, layout->log_attrs, sizeof(PangoLogAttr) * (layout->n_chars + 1));
}
-
+
if (n_attrs)
*n_attrs = layout->n_chars + 1;
}
/**
* pango_layout_get_line_count:
* @layout: #PangoLayout
- *
+ *
* Retrieves the count of lines for the @layout.
- *
+ *
* Return value: the line count.
**/
int
/**
* pango_layout_get_lines:
* @layout: a #PangoLayout
- *
+ *
* Returns the lines of the @layout as a list.
*
* Use the faster pango_layout_get_lines_readonly() if you do not plan
* to modify the contents of the lines (glyphs, glyph widths, etc.).
- *
+ *
* Return value: a #GSList containing the lines in the layout. This
* points to internal data of the #PangoLayout and must be used with
* care. It will become invalid on any change to the layout's
{
PangoLayoutLine *line = tmp_list->data;
tmp_list = tmp_list->next;
-
+
pango_layout_line_leaked (line);
}
}
/**
* pango_layout_get_lines_readonly:
* @layout: a #PangoLayout
- *
+ *
* Returns the lines of the @layout as a list.
- *
+ *
* This is a faster alternative to pango_layout_get_lines(),
* but the user is not expected
* to modify the contents of the lines (glyphs, glyph widths, etc.).
* @layout: a #PangoLayout
* @line: the index of a line, which must be between 0 and
* <literal>pango_layout_get_line_count(layout) - 1</literal>, inclusive.
- *
+ *
* Retrieves a particular line from a #PangoLayout.
- *
+ *
* Use the faster pango_layout_get_line_readonly() if you do not plan
* to modify the contents of the line (glyphs, glyph widths, etc.).
*
* @layout: a #PangoLayout
* @line: the index of a line, which must be between 0 and
* <literal>pango_layout_get_line_count(layout) - 1</literal>, inclusive.
- *
+ *
* Retrieves a particular line from a #PangoLayout.
- *
+ *
* This is a faster alternative to pango_layout_get_line(),
* but the user is not expected
* to modify the contents of the line (glyphs, glyph widths, etc.).
* pango_layout_line_index_to_x:
* @line: a #PangoLayoutLine
* @index_: byte offset of a grapheme within the layout
- * @trailing: an integer indicating the edge of the grapheme to retrieve
- * the position of. If 0, the trailing edge of the grapheme,
+ * @trailing: an integer indicating the edge of the grapheme to retrieve
+ * the position of. If 0, the trailing edge of the grapheme,
* if > 0, the leading of the grapheme.
* @x_pos: location to store the x_offset (in #PangoGlyphUnit)
- *
+ *
* Converts an index within a line to a X position.
*
**/
{
PangoLayoutRun *run = run_list->data;
ItemProperties properties;
-
+
pango_layout_get_item_properties (run->item, &properties);
if (run->item->offset <= index && run->item->offset + run->item->length > index)
offset--;
index = g_utf8_prev_char (layout->text + index) - layout->text;
}
-
+
}
-
+
pango_glyph_string_index_to_x (run->glyphs,
layout->text + run->item->offset,
run->item->length,
if (x_pos)
*x_pos += width;
}
-
+
return;
}
-
+
if (!properties.shape_set)
width += pango_glyph_string_get_width (run->glyphs);
else
PangoLayoutLine *line = NULL;
PangoLayoutLine *prev_line = NULL;
int i = 0;
-
+
line_list = tmp_list = layout->lines;
while (tmp_list)
{
if (line->start_index + line->length > index)
break;
-
+
tmp_list = tmp_list->next;
}
if (line_nr)
*line_nr = i;
-
+
if (line_before)
*line_before = prev_line;
-
+
if (line_after)
*line_after = (line_list && line_list->next) ? line_list->next->data : NULL;
{
PangoLayoutIter *iter;
PangoLayoutLine *line = NULL;
-
+
iter = pango_layout_get_iter (layout);
if (!ITER_IS_INVALID (iter))
break; /* index was in paragraph delimiters */
line = tmp_line;
-
+
pango_layout_iter_get_line_extents (iter, NULL, line_rect);
-
+
if (line->start_index + line->length > index)
break;
* pango_layout_index_to_line_x:
* @layout: a #PangoLayout
* @index_: the byte index of a grapheme within the layout.
- * @trailing: an integer indicating the edge of the grapheme to retrieve the
- * position of. If 0, the trailing edge of the grapheme, if > 0,
+ * @trailing: an integer indicating the edge of the grapheme to retrieve the
+ * position of. If 0, the trailing edge of the grapheme, if > 0,
* the leading of the grapheme.
* @line: location to store resulting line index. (which will
* between 0 and pango_layout_get_line_count(layout) - 1)
{
int line_num;
PangoLayoutLine *layout_line = NULL;
-
+
g_return_if_fail (layout != NULL);
g_return_if_fail (index >= 0);
g_return_if_fail (index <= layout->length);
/* use end of line if index was in the paragraph delimiters */
if (index > layout_line->start_index + layout_line->length)
index = layout_line->start_index + layout_line->length;
-
+
if (line)
*line = line_num;
-
+
pango_layout_line_index_to_x (layout_line, index, trailing, x_pos);
}
else
* weak cursor. The strong cursor is the cursor corresponding
* to text insertion in the base direction for the layout.
* @old_index: the byte index of the grapheme for the old index
- * @old_trailing: if 0, the cursor was at the trailing edge of the
+ * @old_trailing: if 0, the cursor was at the trailing edge of the
* grapheme indicated by @old_index, if > 0, the cursor
* was at the leading edge.
* @direction: direction to move cursor. A negative
* value indicates motion to the left.
- * @new_index: location to store the new cursor byte index. A value of -1
+ * @new_index: location to store the new cursor byte index. A value of -1
* indicates that the cursor has been moved off the beginning
* of the layout. A value of %G_MAXINT indicates that
* the cursor has been moved off the end of the layout.
* be displayed. This allows distinguishing the position at
* the beginning of one line from the position at the end
* of the preceding line. @new_index is always on the line
- * where the cursor should be displayed.
- *
+ * where the cursor should be displayed.
+ *
* Computes a new cursor position from an old position and
* a count of positions to move visually. If @direction is positive,
* then the new strong cursor position will be one position
* to the right of the old cursor position. If @direction is negative,
* then the new strong cursor position will be one position
- * to the left of the old cursor position.
+ * to the left of the old cursor position.
*
* In the presence of bidirectional text, the correspondence
* between logical and visual order will depend on the direction
/* Clamp old_index to fit on the line */
if (old_index > (line->start_index + line->length))
old_index = line->start_index + line->length;
-
+
vis_pos = log2vis_map[old_index - line->start_index];
g_free (log2vis_map);
}
while (vis_pos > 0 && vis_pos < n_vis &&
!layout->log_attrs[start_offset + log_pos].is_cursor_position);
-
+
*new_index = line->start_index + vis2log_map[vis_pos];
g_free (vis2log_map);
*new_trailing = 0;
-
+
if (*new_index == line->start_index + line->length && line->length > 0)
{
do
* be zero, or the number of characters in the
* grapheme. 0 represents the trailing edge of the grapheme.
*
- * Converts from X and Y position within a layout to the byte
+ * Converts from X and Y position within a layout to the byte
* index to the character at that logical position. If the
* Y position is not inside the layout, the closest position is chosen
* (the position will be clamped inside the layout). If the
int prev_line_x = 0;
gboolean retval = FALSE;
gboolean outside = FALSE;
-
+
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), FALSE);
-
+
iter = pango_layout_get_iter (layout);
-
+
do
{
PangoRectangle line_logical;
int first_y, last_y;
-
+
pango_layout_iter_get_line_extents (iter, NULL, &line_logical);
pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);
{
if (prev_line == NULL)
outside = TRUE; /* off the top */
-
+
found = _pango_layout_iter_get_line (iter);
found_line_x = x - line_logical.x;
}
break;
}
while (pango_layout_iter_next_line (iter));
-
+
pango_layout_iter_free (iter);
if (found == NULL)
{
/* Off the bottom of the layout */
outside = TRUE;
-
+
found = prev_line;
found_line_x = prev_line_x;
}
-
+
retval = pango_layout_line_x_to_index (found,
found_line_x,
index, trailing);
* @layout: a #PangoLayout
* @index_: byte index within @layout
* @pos: rectangle in which to store the position of the grapheme
- *
+ *
* Converts from an index within a #PangoLayout to the onscreen position
* corresponding to the grapheme at that index, which is represented
- * as rectangle. Note that <literal>pos->x</literal> is always the leading
- * edge of the grapheme and <literal>pos->x + pos->width</literal> the trailing
+ * as rectangle. Note that <literal>pos->x</literal> is always the leading
+ * edge of the grapheme and <literal>pos->x + pos->width</literal> the trailing
* edge of the grapheme. If the directionality of the grapheme is right-to-left,
* then <literal>pos->width</literal> will be negative.
**/
PangoLayoutIter *iter;
PangoLayoutLine *layout_line = NULL;
int x_pos;
-
+
g_return_if_fail (layout != NULL);
g_return_if_fail (index >= 0);
g_return_if_fail (pos != NULL);
-
+
iter = pango_layout_get_iter (layout);
if (!ITER_IS_INVALID (iter))
}
layout_line = tmp_line;
-
+
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
-
+
if (layout_line->start_index + layout_line->length > index)
break;
else
pos->width = 0;
}
-
+
pango_layout_iter_free (iter);
}
char **end)
{
char *p;
-
+
p = line->layout->text + line->start_index;
if (start)
pango_layout_line_get_range (line, &start, &end);
n_chars = g_utf8_strlen (start, end - start);
-
+
result = g_new (int, n_chars + 1);
if (strong)
if ((cursor_dir == PANGO_DIRECTION_LTR) ||
(prev_dir == run_dir))
result[pos] = p - start;
-
+
p = g_utf8_next_char (p);
-
+
for (i = 1; i < run_n_chars; i++)
{
result[pos + i] = p - start;
p = g_utf8_next_char (p);
}
-
+
if (cursor_dir == PANGO_DIRECTION_LTR)
result[pos + run_n_chars] = p - start;
}
*/
if ((cursor_dir == line->resolved_dir) || (prev_dir == line->resolved_dir))
result[pos] = line->resolved_dir == PANGO_DIRECTION_LTR ? end - start : 0;
-
+
return result;
}
while (run_list)
{
PangoLayoutRun *run = run_list->data;
-
+
if (run->item->offset <= index && run->item->offset + run->item->length > index)
return run->item->analysis.level % 2 ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
* @index_: the byte index of the cursor
* @strong_pos: location to store the strong cursor position (may be %NULL)
* @weak_pos: location to store the weak cursor position (may be %NULL)
- *
+ *
* Given an index within a layout, determines the positions that of the
* strong and weak cursors if the insertion point is at that
* index. The position of each cursor is stored as a zero-width
PangoLayoutLine *layout_line = NULL; /* Quiet GCC */
int x1_trailing;
int x2;
-
+
g_return_if_fail (layout != NULL);
g_return_if_fail (index >= 0 && index <= layout->length);
-
+
layout_line = pango_layout_index_to_line_and_extents (layout, index,
&line_rect);
g_assert (index >= layout_line->start_index);
-
+
/* Examine the trailing edge of the character before the cursor */
if (index == layout_line->start_index)
{
dir1 = pango_layout_line_get_char_direction (layout_line, prev_index);
pango_layout_line_index_to_x (layout_line, prev_index, TRUE, &x1_trailing);
}
-
+
/* Examine the leading edge of the character after the cursor */
if (index >= layout_line->start_index + layout_line->length)
{
{
pango_layout_line_index_to_x (layout_line, index, FALSE, &x2);
}
-
+
if (strong_pos)
{
strong_pos->x = line_rect.x;
-
+
if (dir1 == layout_line->resolved_dir)
strong_pos->x += x1_trailing;
else
if (weak_pos)
{
weak_pos->x = line_rect.x;
-
+
if (dir1 == layout_line->resolved_dir)
weak_pos->x += x2;
else
* indented left/right, though we can't sensibly do that without
* knowing whether left/right is the "normal" thing for this text
*/
-
+
if (alignment == PANGO_ALIGN_CENTER)
return;
-
+
if (line->is_paragraph_start)
{
if (layout->indent > 0)
/* Line extents in line coords (origin at line baseline) */
PangoRectangle line_ink;
PangoRectangle line_logical;
-
+
pango_layout_line_get_extents (line, line_ink_layout ? &line_ink : NULL,
&line_logical);
-
+
get_x_offset (layout, line, layout_width, line_logical.width, &x_offset);
-
+
/* Convert the line's extents into layout coordinates */
if (line_ink_layout)
{
pango_layout_check_lines (layout);
- /* When we are not wrapping, we need the overall width of the layout to
- * figure out the x_offsets of each line. However, we only need the
+ /* When we are not wrapping, we need the overall width of the layout to
+ * figure out the x_offsets of each line. However, we only need the
* x_offsets if we are computing the ink_rect or individual line extents.
*/
width = layout->width;
}
else if (layout->alignment != PANGO_ALIGN_LEFT)
need_width = TRUE;
-
+
if (width == -1 && need_width && (ink_rect || line_extents))
{
PangoRectangle overall_logical;
-
+
pango_layout_get_extents_internal (layout, NULL, &overall_logical, NULL);
width = overall_logical.width;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
logical_rect->width = 0;
logical_rect->height = 0;
}
-
+
line_list = layout->lines;
while (line_list)
{
/* Line extents in layout coords (origin at 0,0 of the layout) */
PangoRectangle line_ink_layout;
PangoRectangle line_logical_layout;
-
+
int new_pos;
/* This block gets the line extents in layout coords */
{
int baseline;
-
+
get_line_extents_layout_coords (layout, line,
width, y_offset,
&baseline,
ink_rect ? &line_ink_layout : NULL,
&line_logical_layout);
-
+
if (line_extents)
{
Extents *ext = g_slice_new (Extents);
*line_extents = g_slist_prepend (*line_extents, ext);
}
}
-
+
if (ink_rect)
{
/* Compute the union of the current ink_rect with
* line_ink_layout
*/
-
+
if (line_list == layout->lines)
{
*ink_rect = line_ink_layout;
MAX (logical_rect->x + logical_rect->width,
line_logical_layout.x + line_logical_layout.width) - new_pos;
logical_rect->x = new_pos;
-
+
}
}
-
+
logical_rect->height += line_logical_layout.height;
/* No space after the last line, of course. */
if (line_list->next != NULL)
logical_rect->height += layout->spacing;
}
-
+
y_offset += line_logical_layout.height + layout->spacing;
line_list = line_list->next;
}
* @layout: a #PangoLayout
* @ink_rect: rectangle used to store the extents of the layout as drawn
* or %NULL to indicate that the result is not needed.
- * @logical_rect: rectangle used to store the logical extents of the layout
+ * @logical_rect: rectangle used to store the logical extents of the layout
or %NULL to indicate that the result is not needed.
- *
+ *
* Computes the logical and ink extents of @layout. Logical extents
* are usually what you want for positioning things. Note that both extents
* may have non-zero x and y. You may want to use those to offset where you
* a set width.
*
* The extents are given in layout coordinates and in Pango units; layout
- * coordinates begin at the top left corner of the layout.
+ * coordinates begin at the top left corner of the layout.
*/
void
pango_layout_get_extents (PangoLayout *layout,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
-{
+{
g_return_if_fail (layout != NULL);
pango_layout_get_extents_internal (layout, ink_rect, logical_rect, NULL);
* @layout: a #PangoLayout
* @ink_rect: rectangle used to store the extents of the layout as drawn
* or %NULL to indicate that the result is not needed.
- * @logical_rect: rectangle used to store the logical extents of the
+ * @logical_rect: rectangle used to store the logical extents of the
* layout or %NULL to indicate that the result is not needed.
- *
+ *
* Computes the logical and ink extents of @layout in device units.
* This function just calls pango_layout_get_extents() followed by
* pango_extents_to_pixels().
* @layout: a #PangoLayout
* @width: location to store the logical width, or %NULL
* @height: location to store the logical height, or %NULL
- *
+ *
* Determines the logical width and height of a #PangoLayout
* in Pango units (device units scaled by %PANGO_SCALE). This
* is simply a convenience function around pango_layout_get_extents().
* @layout: a #PangoLayout
* @width: location to store the logical width, or %NULL
* @height: location to store the logical height, or %NULL
- *
+ *
* Determines the logical width and height of a #PangoLayout
* in device units. (pango_layout_get_size() returns the width
* and height scaled by %PANGO_SCALE.) This
{
PangoLayoutLine *line = tmp_list->data;
tmp_list = tmp_list->next;
-
+
line->layout = NULL;
pango_layout_line_unref (line);
}
-
+
g_slist_free (layout->lines);
layout->lines = NULL;
{
int i;
const char *p;
-
+
pango_glyph_string_set_size (glyphs, n_chars);
for (i=0, p = text; i < n_chars; i++, p = g_utf8_next_char (p))
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->glyphs[i].geometry.width = shape_logical->width;
glyphs->glyphs[i].attr.is_cluster_start = 1;
-
+
glyphs->log_clusters[i] = p - text;
}
}
ink_rect->width = 0;
ink_rect->height = 0;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
{
PangoLayoutRun *run;
PangoItem *item;
-
+
GSList *tmp_node = line->runs;
run = tmp_node->data;
item = run->item;
-
+
line->runs = tmp_node->next;
line->length -= item->length;
-
+
g_slist_free_1 (tmp_node);
free_run (run, (gpointer)FALSE);
layout_attrs = pango_layout_get_effective_attributes (layout);
iter = pango_attr_list_get_iterator (layout_attrs);
pango_attr_iterator_get_font (iter, font_desc, &language, NULL);
-
+
tmp_attrs = pango_attr_list_new ();
attr = pango_attr_font_desc_new (font_desc);
pango_font_description_free (font_desc);
-
+
attr->start_index = 0;
attr->end_index = 1;
pango_attr_list_insert_before (tmp_attrs, attr);
-
+
if (language)
{
attr = pango_attr_language_new (language);
attr->end_index = 1;
pango_attr_list_insert_before (tmp_attrs, attr);
}
-
+
items = pango_itemize (layout->context, " ", 0, 1, tmp_attrs, NULL);
pango_attr_iterator_destroy (iter);
if (layout_attrs != layout->attrs)
pango_attr_list_unref (layout_attrs);
pango_attr_list_unref (tmp_attrs);
-
+
item = items->data;
pango_shape (" ", 8, &item->analysis, glyphs);
-
+
pango_item_free (item);
g_list_free (items);
-
+
layout->tab_width = 0;
for (i=0; i < glyphs->num_glyphs; i++)
layout->tab_width += glyphs->glyphs[i].geometry.width;
-
+
pango_glyph_string_free (glyphs);
/* We need to make sure the tab_width is > 0 so finding tab positions
n_tabs = 0;
in_pixels = FALSE;
}
-
+
if (index < n_tabs)
{
gint pos = 0;
int last_pos = 0;
int next_to_last_pos = 0;
int tab_width;
-
+
pango_tab_array_get_tab (layout->tabs, n_tabs - 1, NULL, &last_pos);
if (n_tabs > 1)
next_to_last_pos *= PANGO_SCALE;
last_pos *= PANGO_SCALE;
}
-
+
if (last_pos > next_to_last_pos)
{
tab_width = last_pos - next_to_last_pos;
GSList *l;
int i;
int width = 0;
-
+
/* Compute the width of the line currently - inefficient, but easier
* than keeping the current width of the line up to date everywhere
*/
for (l = line->runs; l; l = l->next)
{
PangoLayoutRun *run = l->data;
-
+
for (i=0; i < run->glyphs->num_glyphs; i++)
width += run->glyphs->glyphs[i].geometry.width;
}
int current_width = line_width (line);
pango_glyph_string_set_size (glyphs, 1);
-
+
glyphs->glyphs[0].glyph = PANGO_GLYPH_EMPTY;
glyphs->glyphs[0].geometry.x_offset = 0;
glyphs->glyphs[0].geometry.y_offset = 0;
glyphs->glyphs[0].attr.is_cluster_start = 1;
-
+
glyphs->log_clusters[0] = 0;
ensure_tab_width (line->layout);
* editing.
*/
wrap = layout->wrap;
-
+
if (wrap == PANGO_WRAP_WORD_CHAR)
wrap = always_wrap_char ? PANGO_WRAP_CHAR : PANGO_WRAP_WORD;
-
+
if (offset == layout->n_chars)
return TRUE;
else if (wrap == PANGO_WRAP_WORD)
return FALSE;
}
-typedef enum
+typedef enum
{
BREAK_NONE_FIT,
BREAK_SOME_FIT,
{
PangoLayout *layout = line->layout;
PangoGlyphString *glyphs = pango_glyph_string_new ();
-
+
if (layout->text[item->offset] == '\t')
shape_tab (line, glyphs);
else
imposed_shape (layout->text + item->offset, item->num_chars,
state->properties.shape_ink_rect, state->properties.shape_logical_rect,
glyphs);
- else
+ else
pango_shape (layout->text + item->offset, item->length, &item->analysis, glyphs);
if (state->properties.letter_spacing)
{
PangoGlyphItem glyph_item;
-
+
glyph_item.item = item;
glyph_item.glyphs = glyphs;
-
+
pango_glyph_item_letter_space (&glyph_item,
layout->text,
layout->log_attrs + state->start_offset,
state->glyphs = NULL;
g_free (state->log_widths);
}
-
+
line->runs = g_slist_prepend (line->runs, run);
line->length += run_item->length;
}
{
pango_layout_get_item_properties (item, &state->properties);
state->glyphs = shape_run (line, state, item);
-
+
state->log_widths = NULL;
state->log_widths_offset = 0;
state->log_widths_offset += item->num_chars;
return BREAK_LINE_SEPARATOR;
}
-
+
if (state->remaining_width < 0 && !no_break_at_end) /* Wrapping off */
{
insert_run (line, state, item, TRUE);
}
retry_break:
-
+
/* Shorten the item by one line break
*/
while (--num_chars >= 0)
{
break_num_chars = num_chars;
break_width = width;
-
+
if (width <= state->remaining_width || (num_chars == 1 && !line->runs))
break;
}
state->remaining_width -= break_width;
state->remaining_width = MAX (state->remaining_width, 0);
}
-
+
if (break_num_chars == item->num_chars)
{
insert_run (line, state, item, TRUE);
length = g_utf8_offset_to_pointer (layout->text + item->offset, break_num_chars) - (layout->text + item->offset);
new_item = pango_item_split (item, length, break_num_chars);
-
+
insert_run (line, state, new_item, FALSE);
state->log_widths_offset += break_num_chars;
case PANGO_DIRECTION_WEAK_LTR:
case PANGO_DIRECTION_NEUTRAL:
line->resolved_dir = PANGO_DIRECTION_LTR;
- break;
+ break;
case PANGO_DIRECTION_RTL:
case PANGO_DIRECTION_WEAK_RTL:
case PANGO_DIRECTION_TTB_LTR:
ParaBreakState *state)
{
PangoLayoutLine *line;
-
+
gboolean have_break = FALSE; /* If we've seen a possible break yet */
int break_remaining_width = 0; /* Remaining width before adding run with break */
int break_start_offset = 0; /* Start width before adding run with break */
break_start_offset = state->start_offset;
break_link = line->runs->next;
}
-
+
state->items = g_list_delete_link (state->items, state->items);
state->start_offset += old_num_chars;
case BREAK_EMPTY_FIT:
goto done;
-
+
case BREAK_SOME_FIT:
state->start_offset += old_num_chars - item->num_chars;
layout->is_wrapped = TRUE;
goto done;
-
+
case BREAK_NONE_FIT:
/* Back up over unused runs to run where there is a break */
while (line->runs && line->runs != break_link)
/* Reshape run to break */
item = state->items->data;
-
+
old_num_chars = item->num_chars;
result = process_item (layout, line, state, TRUE, TRUE);
g_assert (result == BREAK_SOME_FIT || result == BREAK_EMPTY_FIT);
-
+
state->start_offset += old_num_chars - item->num_chars;
-
+
layout->is_wrapped = TRUE;
goto done;
}
}
- done:
+ done:
pango_layout_line_postprocess (line, state);
layout->lines = g_slist_prepend (layout->lines, line);
state->first_line = FALSE;
{
int offset = 0;
int index = 0;
-
+
while (items)
{
PangoItem tmp_item = *(PangoItem *)items->data;
offset += tmp_item.num_chars;
index += tmp_item.length;
-
+
items = items->next;
}
}
pango_layout_get_effective_attributes (PangoLayout *layout)
{
PangoAttrList *attrs;
-
+
if (layout->attrs)
attrs = pango_attr_list_copy (layout->attrs);
else
PangoAttribute *attr = pango_attr_font_desc_new (layout->font_desc);
attr->start_index = 0;
attr->end_index = layout->length;
-
+
pango_attr_list_insert_before (attrs, attr);
}
PangoLayoutLine *line = line_list->data;
GSList *old_runs = g_slist_reverse (line->runs);
GSList *run_list;
-
+
line->runs = NULL;
for (run_list = old_runs; run_list; run_list = run_list->next)
{
PangoGlyphItem *glyph_item = run_list->data;
GSList *new_runs;
-
+
new_runs = pango_glyph_item_apply_attrs (glyph_item,
layout->text,
no_shape_attrs);
line->runs = g_slist_concat (new_runs, line->runs);
}
-
+
g_slist_free (old_runs);
}
}
PangoAttrList *no_shape_attrs;
PangoAttrIterator *iter;
PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL;
-
+
if (layout->lines)
return;
attrs = pango_layout_get_effective_attributes (layout);
no_shape_attrs = filter_no_shape_attributes (attrs);
iter = pango_attr_list_get_iterator (attrs);
-
+
layout->log_attrs = g_new (PangoLogAttr, layout->n_chars + 1);
-
+
start_offset = 0;
start = layout->text;
-
+
/* Find the first strong direction of the text */
if (layout->auto_dir)
{
if (layout->auto_dir)
{
base_dir = pango_find_base_dir (start, delimiter_index);
-
+
/* Propagate the base direction for neutral paragraphs */
if (base_dir == PANGO_DIRECTION_NEUTRAL)
base_dir = prev_base_dir;
}
end = start + delimiter_index;
-
+
delim_len = next_para_index - delimiter_index;
-
+
if (end == (layout->text + layout->length))
done = TRUE;
state.glyphs = NULL;
state.log_widths = NULL;
-
+
while (state.items)
process_line (layout, &state);
}
/**
* pango_layout_line_ref:
* @line: a #PangoLayoutLine
- *
+ *
* Increase the reference count of a #PangoLayoutLine by one.
*
* Return value: the line passed in.
pango_layout_line_ref (PangoLayoutLine *line)
{
PangoLayoutLinePrivate *private = (PangoLayoutLinePrivate *)line;
-
+
g_return_val_if_fail (line != NULL, NULL);
private->ref_count++;
/**
* pango_layout_line_unref:
* @line: a #PangoLayoutLine
- *
+ *
* Decrease the reference count of a #PangoLayoutLine by one.
* If the result is zero, the line and all associated memory
* will be freed.
pango_layout_line_unref (PangoLayoutLine *line)
{
PangoLayoutLinePrivate *private = (PangoLayoutLinePrivate *)line;
-
+
g_return_if_fail (line != NULL);
g_return_if_fail (private->ref_count > 0);
pango_layout_line_get_type(void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoLayoutLine"),
(GBoxedCopyFunc) pango_layout_line_ref,
*index = first_index;
if (trailing)
*trailing = 0;
-
+
return FALSE;
}
g_assert (line->length > 0);
-
+
first_offset = g_utf8_pointer_to_offset (layout->text, layout->text + line->start_index);
end_index = first_index + line->length;
end_offset = first_offset + g_utf8_pointer_to_offset (layout->text + first_index, layout->text + end_index);
-
+
last_index = end_index;
last_offset = end_offset;
last_trailing = 0;
*
* That is, if the text is "now is the time", and is broken between
* 'now' and 'is'
- *
+ *
* Then when the cursor is actually at:
*
- * n|o|w| |i|s|
+ * n|o|w| |i|s|
* ^
* we lie and say it is at:
*
- * n|o|w| |i|s|
+ * n|o|w| |i|s|
* ^
*
* So the cursor won't appear on the next line before 'the'.
suppress_last_trailing = TRUE;
else
suppress_last_trailing = FALSE;
-
+
if (x_pos < 0)
{
/* pick the leftmost char */
/* and its leftmost edge */
if (trailing)
*trailing = (line->resolved_dir == PANGO_DIRECTION_LTR || suppress_last_trailing) ? 0 : last_trailing;
-
+
return FALSE;
}
grapheme_start_index = g_utf8_prev_char (layout->text + grapheme_start_index) - layout->text;
grapheme_start_offset--;
}
-
+
grapheme_end_offset = offset;
do
{
if (index)
*index = grapheme_start_index;
-
+
if (trailing)
{
if ((grapheme_end_offset == end_offset && suppress_last_trailing) ||
* edge of the layout. Otherwise, it will end at the
* trailing edge of the last character.
* @ranges: location to store a pointer to an array of ranges.
- * The array will be of length <literal>2*n_ranges</literal>,
+ * The array will be of length <literal>2*n_ranges</literal>,
* with each range starting at <literal>(*ranges)[2*n]</literal>
- * and of width <literal>(*ranges)[2*n + 1] - (*ranges)[2*n]</literal>.
- * This array must be freed with g_free(). The coordinates are relative
+ * and of width <literal>(*ranges)[2*n + 1] - (*ranges)[2*n]</literal>.
+ * This array must be freed with g_free(). The coordinates are relative
* to the layout and are in #PangoGlyphUnit.
* @n_ranges: The number of ranges stored in @ranges.
- *
+ *
* Gets a list of visual ranges corresponding to a given logical range.
* This list is not necessarily minimal - there may be consecutive
* ranges which are adjacent. The ranges will be sorted from left to
/* Allocate the maximum possible size */
if (ranges)
*ranges = g_new (int, 2 * (2 + g_slist_length (line->runs)));
-
+
if (x_offset > 0 &&
((line->resolved_dir == PANGO_DIRECTION_LTR && start_index < line_start_index) ||
(line->resolved_dir == PANGO_DIRECTION_RTL && end_index > line_start_index + line->length)))
(*ranges)[2*range_count] = 0;
(*ranges)[2*range_count + 1] = x_offset;
}
-
+
range_count ++;
}
int run_start_x, run_end_x;
g_assert (run_end_index > 0);
-
+
/* Back the end_index off one since we want to find the trailing edge of the preceding character */
run_end_index = g_utf8_prev_char (line->layout->text + run_end_index) - line->layout->text;
(*ranges)[2*range_count] = x_offset + logical_rect.width;
(*ranges)[2*range_count + 1] = line->layout->width;
}
-
+
range_count ++;
}
{
PangoAttrIterator *iter = pango_attr_list_get_iterator (layout->attrs);
int start, end;
-
+
do
{
pango_attr_iterator_range (iter, &start, &end);
-
+
if (start <= index && index < end)
{
PangoFontDescription *base_font_desc;
font_desc = pango_font_description_copy_static (base_font_desc);
free_font_desc = TRUE;
-
+
pango_attr_iterator_get_font (iter,
font_desc,
NULL,
}
while (pango_attr_iterator_next (iter));
-
+
pango_attr_iterator_destroy (iter);
}
else
if (free_font_desc)
pango_font_description_free (font_desc);
-
+
logical_rect->x = 0;
logical_rect->width = 0;
}
if (run_ink && (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough))
{
PangoFontMetrics *metrics = pango_font_get_metrics (run->item->analysis.font,
- run->item->analysis.language);
+ run->item->analysis.language);
int underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
int underline_position = pango_font_metrics_get_underline_position (metrics);
int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
* as drawn, or %NULL
* @logical_rect: rectangle used to store the logical extents of the glyph
* string, or %NULL
- *
+ *
* Computes the logical and ink extents of a layout line. See
* pango_font_get_glyph_extents() for details about the interpretation
* of the rectangles.
GSList *tmp_list;
int x_pos = 0;
gboolean caching = FALSE;
-
+
g_return_if_fail (LINE_IS_VALID (line));
if (!LINE_IS_VALID (line))
ink_rect->width = 0;
ink_rect->height = 0;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
logical_rect->width = 0;
logical_rect->height = 0;
}
-
+
tmp_list = line->runs;
while (tmp_list)
{
pango_layout_run_get_extents (run,
ink_rect ? &run_ink : NULL,
&run_logical);
-
+
if (ink_rect)
{
if (ink_rect->width == 0 || ink_rect->height == 0)
ink_rect->width = MAX (ink_rect->x + ink_rect->width,
x_pos + run_ink.x + run_ink.width) - new_pos;
ink_rect->x = new_pos;
-
+
new_pos = MIN (ink_rect->y, run_ink.y);
ink_rect->height = MAX (ink_rect->y + ink_rect->height,
run_ink.y + run_ink.height) - new_pos;
ink_rect->y = new_pos;
}
}
-
+
if (logical_rect)
{
new_pos = MIN (logical_rect->x, x_pos + run_logical.x);
logical_rect->width = MAX (logical_rect->x + logical_rect->width,
x_pos + run_logical.x + run_logical.width) - new_pos;
logical_rect->x = new_pos;
-
+
new_pos = MIN (logical_rect->y, run_logical.y);
logical_rect->height = MAX (logical_rect->y + logical_rect->height,
run_logical.y + run_logical.height) - new_pos;
logical_rect->y = new_pos;
}
-
+
x_pos += run_logical.width;
tmp_list = tmp_list->next;
}
-
- if (logical_rect && !line->runs)
+
+ if (logical_rect && !line->runs)
pango_layout_line_get_empty_extents (line, logical_rect);
if (caching)
* as drawn, or %NULL
* @logical_rect: rectangle used to store the logical extents of the glyph
* string, or %NULL
- *
+ *
* Computes the logical and ink extents of @layout_line in device units.
* This function just calls pango_layout_line_get_extents() followed by
* pango_extents_to_pixels().
tmp_list = tmp_list->next;
}
-
+
if (min_level % 2)
{
if (i > level_start_i)
PangoLayoutRun *last_run;
int tab_adjustment;
GSList *l;
-
+
/* If we have tab stops and the resolved direction of the
* line is RTL, then we need to walk through the line
* in reverse direction to figure out the corrections for
* which we add onto the next tab stop space to keep the
* things properly aligned.
*/
-
+
last_run = NULL;
tab_adjustment = 0;
for (l = line->runs; l; l = l->next)
PangoLayoutRun *visual_last_run = reversed ? next_run : last_run;
int run_spacing = get_item_letter_spacing (run->item);
int adjustment = run_spacing / 2;
-
+
if (visual_last_run && !is_tab_run (layout, visual_last_run))
adjust_final_space (visual_last_run->glyphs, adjustment);
else
tab_adjustment += adjustment;
-
+
if (visual_next_run && !is_tab_run (layout, visual_next_run))
adjust_final_space (run->glyphs, - adjustment);
else
{
/* NB: the runs are in reverse order at this point, since we prepended them to the list
*/
-
+
/* Reverse the runs
*/
line->runs = g_slist_reverse (line->runs);
*/
if (_pango_layout_line_ellipsize (line, state->attrs))
line->layout->is_ellipsized = TRUE;
-
+
/* Now convert logical to visual order
*/
pango_layout_line_reorder (line);
-
+
/* Fixup letter spacing between runs
*/
adjust_line_letter_spacing (line);
case PANGO_ATTR_STRIKETHROUGH:
properties->strikethrough = ((PangoAttrInt *)attr)->value;
break;
-
+
case PANGO_ATTR_RISE:
properties->rise = ((PangoAttrInt *)attr)->value;
break;
-
+
case PANGO_ATTR_LETTER_SPACING:
properties->letter_spacing = ((PangoAttrInt *)attr)->value;
break;
{
if (gs->glyphs[i].attr.is_cluster_start)
return i;
-
+
i++;
}
{
if (gs->glyphs[i].attr.is_cluster_start)
break;
-
+
width += gs->glyphs[i].geometry.width;
i++;
}
/* Sets up the iter for the start of a new cluster. cluster_start_index
* is the byte index of the cluster start relative to the run.
*/
-static void
+static void
update_cluster (PangoLayoutIter *iter,
int cluster_start_index)
{
Extents *line_ext;
line_ext = (Extents*)iter->line_extents_link->data;
-
+
/* Note that in iter_new() the iter->run_width
* is garbage but we don't use it since we're on the first run of
* a line.
iter->run_x = line_ext->logical_rect.x;
else
iter->run_x += iter->run_width;
-
+
if (iter->run)
{
iter->run_width = pango_layout_run_get_width (iter->run);
GSList *l;
new = g_slice_new (PangoLayoutIter);
-
+
new->layout = g_object_ref (iter->layout);
new->line_list_link = iter->line_list_link;
new->line = iter->line;
new->line_extents_link = new->line_extents;
}
new->line_extents = g_slist_reverse (new->line_extents);
-
+
new->run_x = iter->run_x;
new->run_width = iter->run_width;
new->ltr = iter->ltr;
-
+
new->cluster_x = iter->cluster_x;
new->cluster_width = iter->cluster_width;
pango_layout_iter_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoLayoutIter"),
(GBoxedCopyFunc)pango_layout_iter_copy,
/**
* pango_layout_get_iter:
* @layout: a #PangoLayout
- *
+ *
* Returns an iterator to iterate over the visual extents of the layout.
- *
+ *
* Return value: the new #PangoLayoutIter that should be freed using
* pango_layout_iter_free().
**/
int run_start_index;
PangoLayoutIter *iter;
PangoRectangle logical_rect;
-
+
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
-
+
iter = g_slice_new (PangoLayoutIter);
iter->layout = layout;
g_object_ref (iter->layout);
pango_layout_check_lines (layout);
-
+
iter->line_list_link = layout->lines;
iter->line = iter->line_list_link->data;
pango_layout_line_ref (iter->line);
/**
* pango_layout_iter_free:
* @iter: a #PangoLayoutIter
- *
+ *
* Frees an iterator that's no longer in use.
**/
void
/**
* pango_layout_iter_get_index:
* @iter: a #PangoLayoutIter
- *
+ *
* Gets the current byte index. Note that iterating forward by char
* moves in visual order, not logical order, so indexes may not be
* sequential. Also, the index may be equal to the length of the text
* in the layout, if on the %NULL run (see pango_layout_iter_get_run()).
- *
+ *
* Return value: current byte index.
**/
int
{
if (ITER_IS_INVALID (iter))
return 0;
-
+
return iter->index;
}
/**
* pango_layout_iter_get_run:
* @iter: a #PangoLayoutIter
- *
+ *
* Gets the current run. When iterating by run, at the end of each
* line, there's a position with a %NULL run, so this function can return
* %NULL. The %NULL run at the end of each line ensures that all lines have
*
* Use the faster pango_layout_iter_get_run_readonly() if you do not plan
* to modify the contents of the run (glyphs, glyph widths, etc.).
- *
+ *
* Return value: the current run.
**/
PangoLayoutRun*
/**
* pango_layout_iter_get_run_readonly:
* @iter: a #PangoLayoutIter
- *
+ *
* Gets the current run. When iterating by run, at the end of each
* line, there's a position with a %NULL run, so this function can return
* %NULL. The %NULL run at the end of each line ensures that all lines have
* at least one run, even lines consisting of only a newline.
- *
+ *
* This is a faster alternative to pango_layout_iter_get_run(),
* but the user is not expected
* to modify the contents of the run (glyphs, glyph widths, etc.).
- *
+ *
* Return value: the current run, that should not be modified.
*
* Since: 1.16
/**
* pango_layout_iter_get_line:
* @iter: a #PangoLayoutIter
- *
+ *
* Gets the current line.
*
* Use the faster pango_layout_iter_get_line_readonly() if you do not plan
* to modify the contents of the line (glyphs, glyph widths, etc.).
- *
+ *
* Return value: the current line.
**/
PangoLayoutLine*
/**
* pango_layout_iter_get_line_readonly:
* @iter: a #PangoLayoutIter
- *
+ *
* Gets the current line for read-only access.
*
* This is a faster alternative to pango_layout_iter_get_line(),
* but the user is not expected
* to modify the contents of the line (glyphs, glyph widths, etc.).
- *
+ *
* Return value: the current line, that should not be modified.
*
* Since: 1.16
/**
* pango_layout_iter_at_last_line:
* @iter: a #PangoLayoutIter
- *
+ *
* Determines whether @iter is on the last line of the layout.
- *
+ *
* Return value: %TRUE if @iter is on the last line.
**/
gboolean
result = pango_layout_iter_next_line (iter);
if (!result)
break;
-
+
if (iter->line->runs)
break;
-
+
if (include_terminators && line_is_terminated (iter))
break;
}
-
+
return result;
}
gboolean include_terminators)
{
gboolean result;
-
+
while (TRUE)
{
result = pango_layout_iter_next_run (iter);
if (!result)
break;
-
+
if (iter->run)
break;
-
+
if (include_terminators && line_is_terminated (iter))
break;
}
-
+
return result;
}
{
PangoGlyphString *gs;
int next_start;
-
+
if (ITER_IS_INVALID (iter))
return FALSE;
if (iter->run == NULL)
return next_nonempty_line (iter, include_terminators);
-
+
gs = iter->run->glyphs;
-
+
next_start = iter->next_cluster_glyph;
if (next_start == gs->num_glyphs)
{
/**
* pango_layout_iter_next_char:
* @iter: a #PangoLayoutIter
- *
+ *
* Moves @iter forward to the next character in visual order. If @iter was already at
* the end of the layout, returns %FALSE.
- *
+ *
* Return value: whether motion was possible.
**/
gboolean
iter->character_position++;
if (iter->character_position >= iter->cluster_num_chars)
return next_cluster_internal (iter, TRUE);
-
+
text = iter->layout->text;
if (iter->ltr)
iter->index = g_utf8_next_char (text + iter->index) - text;
else
iter->index = g_utf8_prev_char (text + iter->index) - text;
-
+
return TRUE;
}
/**
* pango_layout_iter_next_cluster:
* @iter: a #PangoLayoutIter
- *
+ *
* Moves @iter forward to the next cluster in visual order. If @iter
* was already at the end of the layout, returns %FALSE.
- *
+ *
* Return value: whether motion was possible.
**/
gboolean
/**
* pango_layout_iter_next_run:
* @iter: a #PangoLayoutIter
- *
+ *
* Moves @iter forward to the next run in visual order. If @iter was
* already at the end of the layout, returns %FALSE.
- *
+ *
* Return value: whether motion was possible.
**/
gboolean
{
int next_run_start; /* byte index */
GSList *next_link;
-
+
if (ITER_IS_INVALID (iter))
return FALSE;
/* Moving on to the zero-width "virtual run" at the end of each
* line
*/
- next_run_start = iter->run->item->offset + iter->run->item->length;
+ next_run_start = iter->run->item->offset + iter->run->item->length;
iter->run = NULL;
iter->run_list_link = NULL;
}
iter->run = iter->run_list_link->data;
next_run_start = iter->run->item->offset;
}
-
+
update_run (iter, next_run_start);
-
+
return TRUE;
}
/**
* pango_layout_iter_next_line:
* @iter: a #PangoLayoutIter
- *
+ *
* Moves @iter forward to the start of the next line. If @iter is
* already on the last line, returns %FALSE.
- *
+ *
* Return value: whether motion was possible.
**/
gboolean
iter->line_list_link = next_link;
pango_layout_line_unref (iter->line);
-
+
iter->line = iter->line_list_link->data;
pango_layout_line_ref (iter->line);
iter->run = NULL;
iter->line_extents_link = iter->line_extents_link->next;
- g_assert (iter->line_extents_link != NULL);
+ g_assert (iter->line_extents_link != NULL);
update_run (iter, iter->line->start_index);
-
+
return TRUE;
}
* pango_layout_iter_get_char_extents:
* @iter: a #PangoLayoutIter
* @logical_rect: rectangle to fill with logical extents
- *
+ *
* Gets the extents of the current character, in layout coordinates
* (origin is the top left of the entire layout). Only logical extents
* can sensibly be obtained for characters; ink extents make sense only
* down to the level of clusters.
- *
+ *
**/
void
pango_layout_iter_get_char_extents (PangoLayoutIter *iter,
*logical_rect = cluster_rect;
return;
}
-
+
x0 = (iter->character_position * cluster_rect.width) / iter->cluster_num_chars;
x1 = ((iter->character_position + 1) * cluster_rect.width) / iter->cluster_num_chars;
*
* Gets the extents of the current cluster, in layout coordinates
* (origin is the top left of the entire layout).
- *
+ *
**/
void
pango_layout_iter_get_cluster_extents (PangoLayoutIter *iter,
pango_layout_iter_get_run_extents (iter, ink_rect, logical_rect);
return;
}
-
+
pango_glyph_string_extents_range (iter->run->glyphs,
iter->cluster_start,
iter->next_cluster_glyph,
* @iter: a #PangoLayoutIter
* @ink_rect: rectangle to fill with ink extents, or %NULL
* @logical_rect: rectangle to fill with logical extents, or %NULL
- *
+ *
* Gets the extents of the current run in layout coordinates
* (origin is the top left of the entire layout).
- *
+ *
**/
void
pango_layout_iter_get_run_extents (PangoLayoutIter *iter,
else
{
/* The empty run at the end of a line */
-
+
pango_layout_iter_get_line_extents (iter, ink_rect, logical_rect);
if (ink_rect)
{
- ink_rect->x = iter->run_x;
+ ink_rect->x = iter->run_x;
ink_rect->width = 0;
}
* #PangoLayout). Thus the extents returned by this function will be
* the same width/height but not at the same x/y as the extents
* returned from pango_layout_line_get_extents().
- *
+ *
**/
void
pango_layout_iter_get_line_extents (PangoLayoutIter *iter,
PangoRectangle *logical_rect)
{
Extents *ext;
-
+
if (ITER_IS_INVALID (iter))
return;
ink_rect,
NULL);
}
-
+
if (logical_rect)
*logical_rect = ext->logical_rect;
}
/**
* pango_layout_iter_get_line_yrange:
* @iter: a #PangoLayoutIter
- * @y0_: start of line
+ * @y0_: start of line
* @y1_: end of line
*
* Divides the vertical space in the #PangoLayout being iterated over
* pango_layout_set_spacing() has been called to set layout spacing.
* The Y positions are in layout coordinates (origin at top left of the
* entire layout).
- *
+ *
**/
void
pango_layout_iter_get_line_yrange (PangoLayoutIter *iter,
{
Extents *ext;
int half_spacing;
-
+
if (ITER_IS_INVALID (iter))
return;
/* Note that if layout->spacing is odd, the remainder spacing goes
* above the line (this is pretty arbitrary of course)
*/
-
+
if (y0)
{
/* No spacing above the first line */
-
+
if (iter->line_extents_link == iter->line_extents)
*y0 = ext->logical_rect.y;
else
/**
* pango_layout_iter_get_baseline:
* @iter: a #PangoLayoutIter
- *
+ *
* Gets the Y position of the current line's baseline, in layout
* coordinates (origin at top left of the entire layout).
- *
+ *
* Return value: baseline of current line.
**/
int
pango_layout_iter_get_baseline (PangoLayoutIter *iter)
{
Extents *ext;
-
+
if (ITER_IS_INVALID (iter))
return 0;
* Obtains the extents of the #PangoLayout being iterated
* over. @ink_rect or @logical_rect can be %NULL if you
* aren't interested in them.
- *
+ *
**/
void
pango_layout_iter_get_layout_extents (PangoLayoutIter *iter,
* @PANGO_ELLIPSIZE_START: Omit characters at the start of the text
* @PANGO_ELLIPSIZE_MIDDLE: Omit characters in the middle of the text
* @PANGO_ELLIPSIZE_END: Omit characters at the end of the text
- *
+ *
* The #PangoEllipsizeMode type describes what sort of (if any)
* ellipsization should be applied to a line of text. In
* the ellipsization process characters are removed from the
gint start_index; /* start of line as byte index into layout->text */
gint length; /* length of line in bytes */
GSList *runs;
- guint is_paragraph_start : 1; /* TRUE if this is the first line of the paragraph */
+ guint is_paragraph_start : 1; /* TRUE if this is the first line of the paragraph */
guint resolved_dir : 3; /* Resolved PangoDirection of line */
};
int i;
/* 1.2 is the CSS scale factor between sizes */
-
+
if (scale_level > 0)
{
i = 0;
while (i < 0)
{
factor /= 1.2;
-
+
++i;
}
}
ot->scale_level = 0;
ot->scale_level_delta = 0;
}
-
+
static OpenTag*
markup_data_open_tag (MarkupData *md)
{
OpenTag *ot;
OpenTag *parent = NULL;
-
+
if (md->attr_list == NULL)
return NULL;
if (md->tag_stack)
parent = md->tag_stack->data;
-
+
ot = g_slice_new (OpenTag);
ot->attrs = NULL;
ot->start_index = md->index;
ot->scale_level_delta = 0;
-
+
if (parent == NULL)
{
ot->base_scale_factor = 1.0;
ot->has_base_font_size = parent->has_base_font_size;
ot->scale_level = parent->scale_level;
}
-
+
md->tag_stack = g_slist_prepend (md->tag_stack, ot);
return ot;
a->start_index = ot->start_index;
a->end_index = md->index;
-
+
md->to_apply = g_slist_prepend (md->to_apply, a);
tmp_list = g_slist_next (tmp_list);
a->start_index = ot->start_index;
a->end_index = md->index;
-
+
md->to_apply = g_slist_prepend (md->to_apply, a);
}
-
+
g_slist_free (ot->attrs);
- g_slice_free (OpenTag, ot);
+ g_slice_free (OpenTag, ot);
}
static void
if (md->accel_marker == 0)
{
/* Just append all the text */
-
+
md->index += text_len;
-
+
g_string_append_len (md->text, text, text_len);
}
else
const gchar *range_end;
gssize uline_index = -1;
gsize uline_len = 0; /* Quiet GCC */
-
+
range_end = NULL;
range_start = text;
p = text;
end = text + text_len;
-
+
while (p != end)
{
gunichar c;
-
+
c = g_utf8_get_char (p);
if (range_end)
*/
uline_index = md->index;
uline_len = g_utf8_next_char (p) - p;
-
+
/* set next range_start to include this char */
range_start = p;
}
/* reset range_end */
range_end = NULL;
- }
+ }
else if (c == md->accel_marker)
{
range_end = p;
}
-
+
p = g_utf8_next_char (p);
}
end - range_start);
md->index += end - range_start;
}
-
+
if (md->attr_list != NULL && uline_index >= 0)
{
- /* Add the underline indicating the accelerator */
+ /* Add the underline indicating the accelerator */
PangoAttribute *attr;
attr = pango_attr_underline_new (PANGO_UNDERLINE_LOW);
attr->start_index = uline_index;
attr->end_index = uline_index + uline_len;
-
+
pango_attr_list_change (md->attr_list, attr);
}
}
* @text: address of return location for text with tags stripped, or %NULL
* @accel_char: address of return location for accelerator char, or %NULL
* @error: address of return location for errors, or %NULL
- *
+ *
*
* Parses marked-up text (see
* <link linkend="PangoMarkupFormat">markup format</link>) to create
* and the first character so marked will be returned in @accel_char.
* Two @accel_marker characters following each other produce a single
* literal @accel_marker character.
- *
+ *
* Return value: %FALSE if @error is set, otherwise %TRUE
**/
gboolean
GSList *tmp_list;
const char *p;
const char *end;
-
+
g_return_val_if_fail (markup_text != NULL, FALSE);
-
+
md = g_slice_new (MarkupData);
/* Don't bother creating these if they weren't requested;
md->attr_list = NULL;
md->text = g_string_new (NULL);
-
+
if (accel_char)
*accel_char = 0;
md->accel_marker = accel_marker;
md->accel_char = 0;
-
+
md->index = 0;
md->tag_stack = NULL;
md->to_apply = NULL;
-
+
context = g_markup_parse_context_new (&pango_markup_parser,
0, md, NULL);
if (length < 0)
- length = strlen (markup_text);
+ length = strlen (markup_text);
p = markup_text;
end = markup_text + length;
while (tmp_list != NULL)
{
PangoAttribute *attr = tmp_list->data;
-
+
/* Innermost tags before outermost */
pango_attr_list_change (md->attr_list, attr);
g_slist_free (md->to_apply);
md->to_apply = NULL;
}
-
+
if (attr_list)
*attr_list = md->attr_list;
*text = g_string_free (md->text, FALSE);
else
g_string_free (md->text, TRUE);
-
+
if (accel_char)
*accel_char = md->accel_char;
-
+
g_assert (md->tag_stack == NULL);
-
+
g_slice_free (MarkupData, md);
return TRUE;
g_slist_foreach (md->to_apply, (GFunc) pango_attribute_destroy, NULL);
g_slist_free (md->to_apply);
g_string_free (md->text, TRUE);
-
+
if (md->attr_list)
pango_attr_list_unref (md->attr_list);
{
SizeLevel level = Medium;
double factor;
-
+
if (strcmp (size, "xx-small") == 0)
level = XXSmall;
else if (strcmp (size, "x-small") == 0)
add_attribute (tag, pango_attr_scale_new (factor));
if (tag)
open_tag_set_absolute_font_scale (tag, factor);
-
+
return TRUE;
}
const char *fallback = NULL;
const char *gravity = NULL;
const char *gravity_hint = NULL;
-
+
g_markup_parse_context_get_position (context,
&line_number, &char_number);
if (G_UNLIKELY (style))
{
PangoStyle pango_style;
-
+
if (pango_parse_style (style, &pango_style, FALSE))
add_attribute (tag, pango_attr_style_new (pango_style));
else
if (G_UNLIKELY (weight))
{
PangoWeight pango_weight;
-
+
if (pango_parse_weight (weight, &pango_weight, FALSE))
add_attribute (tag,
pango_attr_weight_new (pango_weight));
if (G_UNLIKELY (variant))
{
PangoVariant pango_variant;
-
+
if (pango_parse_variant (variant, &pango_variant, FALSE))
add_attribute (tag, pango_attr_variant_new (pango_variant));
else
if (G_UNLIKELY (stretch))
{
PangoStretch pango_stretch;
-
+
if (pango_parse_stretch (stretch, &pango_stretch, FALSE))
add_attribute (tag, pango_attr_stretch_new (pango_stretch));
else
if (G_UNLIKELY (background))
{
PangoColor color;
-
+
if (!span_parse_color ("background", background, &color, line_number, error))
goto error;
if (G_UNLIKELY (letter_spacing))
{
gint n = 0;
-
+
if (!span_parse_int ("letter_spacing", letter_spacing, &n, line_number, error))
goto error;
add_attribute (tag,
pango_attr_language_new (pango_language_from_string (lang)));
}
-
+
return TRUE;
error:
GError **error)
{
/* We don't do anything with this tag at the moment. */
-
+
return TRUE;
}
pango_matrix_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoMatrix"),
(GBoxedCopyFunc) pango_matrix_copy,
/**
* pango_matrix_copy:
* @matrix: a #PangoMatrix, can be %NULL
- *
+ *
* Copies a #PangoMatrix.
- *
+ *
* Return value: the newly allocated #PangoMatrix, which should
* be freed with pango_matrix_free(), or %NULL if
* @matrix was %NULL.
/**
* pango_matrix_free:
* @matrix: a #PangoMatrix, or %NULL
- *
+ *
* Free a #PangoMatrix created with pango_matrix_copy().
* Does nothing if @matrix is %NULL.
*
* @matrix: a #PangoMatrix
* @tx: amount to translate in the X direction
* @ty: amount to translate in the Y direction
- *
+ *
* Changes the transformation represented by @matrix to be the
* transformation given by first translating by (@tx, @ty)
* then applying the original transformation.
* @matrix: a #PangoMatrix
* @scale_x: amount to scale by in X direction
* @scale_y: amount to scale by in Y direction
- *
+ *
* Changes the transformation represented by @matrix to be the
* transformation given by first scaling by @sx in the X direction
* and @sy in the Y direction then applying the original
* pango_matrix_rotate:
* @matrix: a #PangoMatrix
* @degrees: degrees to rotate counter-clockwise
- *
+ *
* Changes the transformation represented by @matrix to be the
* transformation given by first rotating by @degrees degrees
* counter-clockwise then applying the original transformation.
* pango_matrix_concat:
* @matrix: a #PangoMatrix
* @new_matrix: a #PangoMatrix
- *
+ *
* Changes the transformation represented by @matrix to be the
* transformation given by first applying transformation
* given by @new_matrix then applying the original transformation.
const PangoMatrix *new_matrix)
{
PangoMatrix tmp;
-
+
g_return_if_fail (matrix != NULL);
tmp = *matrix;
/**
* pango_matrix_get_font_scale_factor:
* @matrix: a #PangoMatrix, may be %NULL
- *
+ *
* Returns the scale factor of a matrix on the height of the font.
* That is, the scale factor in the direction perpendicular to the
* vector that the X coordinate is mapped to.
* Copyright 2005, Keith Packard
*/
double det;
-
+
if (!matrix)
return 1.0;
-
+
det = matrix->xx * matrix->yy - matrix->yx * matrix->xy;
if (det == 0)
double major, minor;
major = sqrt (x*x + y*y);
-
+
/*
* ignore mirroring
*/
if (det < 0)
det = - det;
-
+
if (major)
minor = det / major;
- else
+ else
minor = 0.0;
return minor;
* @matrix: a #PangoMatrix, or %NULL
* @x: in/out X position
* @y: in/out Y position
- *
+ *
* Transforms the point (@x, @y) by @matrix.
*
* Since: 1.16
* pango_matrix_transform_rectangle:
* @matrix: a #PangoMatrix, or %NULL
* @rect: in/out bounding box in Pango units, or %NULL
- *
+ *
* First transforms @rect using @matrix, then calculates the bounding box
* of the transformed rectangle. The rectangle should be in Pango units.
*
* pango_matrix_transform_pixel_rectangle:
* @matrix: a #PangoMatrix, or %NULL
* @rect: in/out bounding box in device units, or %NULL
- *
+ *
* First transforms the @rect using @matrix, then calculates the bounding box
* of the transformed rectangle. The rectangle should be in device units
* (pixels).
* be freed with pango_ot_buffer_destroy().
*
* Since: 1.4
- **/
+ **/
PangoOTBuffer *
pango_ot_buffer_new (PangoFcFont *font)
{
* Destroys a #PangoOTBuffer and free all associated memory.
*
* Since: 1.4
- **/
+ **/
void
pango_ot_buffer_destroy (PangoOTBuffer *buffer)
{
* Empties a #PangoOTBuffer, make it ready to add glyphs to.
*
* Since: 1.4
- **/
+ **/
void
pango_ot_buffer_clear (PangoOTBuffer *buffer)
{
* features should be applied on this glyph. See pango_ruleset_add_feature().
*
* Since: 1.4
- **/
+ **/
void
pango_ot_buffer_add_glyph (PangoOTBuffer *buffer,
guint glyph,
* is needed for proper horizontal positioning of right-to-left scripts.
*
* Since: 1.4
- **/
+ **/
void
pango_ot_buffer_set_rtl (PangoOTBuffer *buffer,
gboolean rtl)
* @buffer: a #PangoOTBuffer
* @zero_width_marks: %TRUE if characters with a mark class should
* be forced to zero width.
- *
+ *
* Sets whether characters with a mark class should be forced to zero width.
* This setting is needed for proper positioning of Arabic accents,
* but will produce incorrect results with standard OpenType Indic
* as buffer is not modified.
*
* Since: 1.4
- **/
+ **/
void
pango_ot_buffer_get_glyphs (PangoOTBuffer *buffer,
PangoOTGlyph **glyphs,
swap_range (PangoGlyphString *glyphs, int start, int end)
{
int i, j;
-
+
for (i = start, j = end - 1; i < j; i++, j--)
{
PangoGlyphInfo glyph_info;
gint log_cluster;
-
+
glyph_info = glyphs->glyphs[i];
glyphs->glyphs[i] = glyphs->glyphs[j];
glyphs->glyphs[j] = glyph_info;
-
+
log_cluster = glyphs->log_clusters[i];
glyphs->log_clusters[i] = glyphs->log_clusters[j];
glyphs->log_clusters[j] = log_cluster;
HB_Position positions)
{
int i;
-
+
for (i = 0; i < glyphs->num_glyphs; i++)
{
FT_Pos x_pos = positions[i].x_pos;
FT_Pos y_pos = positions[i].y_pos;
int back = i;
int j;
-
+
while (positions[back].back != 0)
{
back -= positions[back].back;
x_pos += positions[back].x_pos;
y_pos += positions[back].y_pos;
}
-
+
for (j = back; j < i; j++)
glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[j].geometry.width;
-
+
glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos);
glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos);
-
+
if (positions[i].new_advance)
glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(positions[i].x_advance);
else
HB_Position positions)
{
int i;
-
+
for (i = 0; i < glyphs->num_glyphs; i++)
{
int i_rev = glyphs->num_glyphs - i - 1;
}
back = glyphs->num_glyphs - back_rev - 1;
-
+
for (j = i; j < back; j++)
glyphs->glyphs[i].geometry.x_offset += glyphs->glyphs[j].geometry.width;
-
+
glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos);
glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos);
-
+
if (positions[i_rev].new_advance)
glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(positions[i_rev].x_advance);
else
* resulting glyphs into a generic Pango glyph string.
*
* Since: 1.4
- **/
+ **/
void
pango_ot_buffer_output (PangoOTBuffer *buffer,
PangoGlyphString *glyphs)
face = pango_fc_font_lock_face (buffer->font);
g_assert (face);
-
+
/* Copy glyphs into output glyph string */
pango_glyph_string_set_size (glyphs, buffer->buffer->in_length);
for (i = 0; i < buffer->buffer->in_length; i++)
{
HB_GlyphItem item = &buffer->buffer->in_string[i];
-
+
glyphs->glyphs[i].glyph = item->gindex;
glyphs->log_clusters[i] = item->cluster;
info = pango_ot_info_get (face);
gdef = pango_ot_info_get_gdef (info);
-
+
/* Apply default positioning */
for (i = 0; i < (unsigned int)glyphs->num_glyphs; i++)
{
if (glyphs->glyphs[i].glyph)
{
PangoRectangle logical_rect;
-
+
FT_UShort property;
if (buffer->zero_width_marks &&
}
else
glyphs->glyphs[i].geometry.width = 0;
-
+
glyphs->glyphs[i].geometry.x_offset = 0;
glyphs->glyphs[i].geometry.y_offset = 0;
}
NULL, /* init */
NULL, /* value_table */
};
-
+
object_type = g_type_register_static (G_TYPE_OBJECT,
I_("PangoOTInfo"),
&object_info, 0);
}
-
+
return object_type;
}
-static void
+static void
pango_ot_info_class_init (GObjectClass *object_class)
{
parent_class = g_type_class_peek_parent (object_class);
-
+
object_class->finalize = pango_ot_info_finalize;
}
-static void
+static void
pango_ot_info_finalize (GObject *object)
{
PangoOTInfo *info = PANGO_OT_INFO (object);
-
+
if (info->gdef)
{
HB_Done_GDEF_Table (info->gdef);
static void
pango_ot_info_finalizer (void *object)
{
- FT_Face face = object;
+ FT_Face face = object;
PangoOTInfo *info = face->generic.data;
-
+
info->face = NULL;
g_object_unref (info);
}
/**
* pango_ot_info_get:
* @face: a <type>FT_Face</type>.
- *
+ *
* Returns the #PangoOTInfo structure for the given FreeType font.
*
* Return value: the #PangoOTInfo for @face. This object will have
{
info = face->generic.data = g_object_new (PANGO_TYPE_OT_INFO, NULL);
face->generic.finalizer = pango_ot_info_finalizer;
-
+
info->face = face;
}
(info_a->glyph == info_b->glyph) ? 0 : 1;
}
-/* Make a guess at the appropriate class for a glyph given
+/* Make a guess at the appropriate class for a glyph given
* a character code that maps to the glyph
*/
static gboolean
if ((charcode >= 0xFB50 && charcode <= 0xFDFF) || /* Arabic Presentation Forms-A */
(charcode >= 0xFE70 && charcode <= 0XFEFF)) /* Arabic Presentation Forms-B */
return FALSE;
-
+
switch (g_unichar_type (charcode))
{
case G_UNICODE_COMBINING_MARK:
FT_UInt glyph;
unsigned int i, j;
FT_CharMap old_charmap;
-
+
old_charmap = info->face->charmap;
if (!old_charmap || !old_charmap->encoding != ft_encoding_unicode)
if (get_glyph_class (charcode, &glyph_info.class))
g_array_append_val (glyph_infos, glyph_info);
}
-
+
charcode = FT_Get_Next_Char (info->face, charcode, &glyph);
}
{
glyph_indices[j] = info->glyph;
classes[j] = info->class;
-
+
j++;
}
}
FT_Set_Charmap (info->face, old_charmap);
}
-HB_GDEF
+HB_GDEF
pango_ot_info_get_gdef (PangoOTInfo *info)
{
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
if (!(info->loaded & INFO_LOADED_GDEF))
{
FT_Error error;
-
+
info->loaded |= INFO_LOADED_GDEF;
if (is_truetype (info->face))
{
error = HB_Load_GDEF_Table (info->face, &info->gdef);
-
+
if (error && error != FT_Err_Table_Missing)
g_warning ("Error loading GDEF table %d", error);
pango_ot_info_get_gsub (PangoOTInfo *info)
{
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
-
+
if (!(info->loaded & INFO_LOADED_GSUB))
{
FT_Error error;
HB_GDEF gdef = pango_ot_info_get_gdef (info);
-
+
info->loaded |= INFO_LOADED_GSUB;
if (is_truetype (info->face))
g_warning ("Error loading GSUB table %d", error);
}
}
-
+
return info->gsub;
}
pango_ot_info_get_gpos (PangoOTInfo *info)
{
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
-
+
if (!(info->loaded & INFO_LOADED_GPOS))
{
FT_Error error;
* @table_type: the table type to obtain information about.
* @script_tag: the tag of the script to find.
* @script_index: location to store the index of the script, or %NULL.
- *
+ *
* Finds the index of a script.
*
* Return value: %TRUE if the script was found.
**/
-gboolean
+gboolean
pango_ot_info_find_script (PangoOTInfo *info,
PangoOTTableType table_type,
PangoOTTag script_tag,
* @script_index: the index of the script whose languages are searched.
* @language_tag: the tag of the language to find.
* @language_index: location to store the index of the language, or %NULL.
- * @required_feature_index: location to store the required feature index of
+ * @required_feature_index: location to store the required feature index of
* the language, or %NULL.
- *
- * Finds the index of a language and its required feature index.
+ *
+ * Finds the index of a language and its required feature index.
*
* Return value: %TRUE if the language was found.
**/
* @script_index: the index of the script.
* @language_index: the index of the language whose features are searched,
* or %PANGO_OT_DEFAULT_LANGUAGE to use the default language of the script.
- * @feature_index: location to store the index of the feature, or %NULL.
- *
+ * @feature_index: location to store the index of the feature, or %NULL.
+ *
* Finds the index of a feature.
*
* Return value: %TRUE if the feature was found.
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
*
- * Obtains the list of available scripts.
+ * Obtains the list of available scripts.
*
* Return value: a newly-allocated array containing the tags of the
* available scripts.
return NULL;
result = g_new (PangoOTTag, script_list->ScriptCount + 1);
-
+
for (i=0; i < script_list->ScriptCount; i++)
result[i] = script_list->ScriptRecord[i].ScriptTag;
* @table_type: the table type to obtain information about.
* @script_index: the index of the script to list languages for.
* @language_tag: unused parameter.
- *
+ *
* Obtains the list of available languages for a given script.
*
* Return value: a newly-allocated array containing the tags of the
* available languages.
- **/
+ **/
PangoOTTag *
pango_ot_info_list_languages (PangoOTInfo *info,
PangoOTTableType table_type,
g_return_val_if_fail (script_index < script_list->ScriptCount, NULL);
script = &script_list->ScriptRecord[script_index].Script;
-
+
result = g_new (PangoOTTag, script->LangSysCount + 1);
-
+
for (i = 0; i < script->LangSysCount; i++)
result[i] = script->LangSysRecord[i].LangSysTag;
return result;
}
-/**
+/**
* pango_ot_info_list_features:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
* @tag: unused parameter.
- * @script_index: the index of the script to obtain information about.
+ * @script_index: the index of the script to obtain information about.
* @language_index: the index of the language to list features for, or
* %PANGO_OT_DEFAULT_LANGUAGE, to list features for the default
* language of the script.
* Obtains the list of features for the given language of the given script.
*
* Return value: a newly-allocated array containing the tags of the
- * available features.
+ * available features.
**/
PangoOTTag *
pango_ot_info_list_features (PangoOTInfo *info,
}
result = g_new (PangoOTTag, lang_sys->FeatureCount + 1);
-
+
for (i = 0; i < lang_sys->FeatureCount; i++)
{
FT_UShort index = lang_sys->FeatureIndex[i];
typedef struct _PangoOTInfoClass PangoOTInfoClass;
-struct _PangoOTInfo
+struct _PangoOTInfo
{
GObject parent_instance;
typedef struct _PangoOTRule PangoOTRule;
-struct _PangoOTRule
+struct _PangoOTRule
{
gulong property_bit;
FT_UShort feature_index;
(GInstanceInitFunc)pango_ot_ruleset_init,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (G_TYPE_OBJECT,
I_("PangoOTRuleset"),
&object_info, 0);
}
-
+
return object_type;
}
-static void
+static void
pango_ot_ruleset_class_init (GObjectClass *object_class)
{
parent_class = g_type_class_peek_parent (object_class);
-
+
object_class->finalize = pango_ot_ruleset_finalize;
}
-static void
+static void
pango_ot_ruleset_init (PangoOTRuleset *ruleset)
{
ruleset->rules = g_array_new (FALSE, FALSE, sizeof (PangoOTRule));
}
-static void
+static void
pango_ot_ruleset_finalize (GObject *object)
{
PangoOTRuleset *ruleset = PANGO_OT_RULESET (object);
PangoOTBuffer *buffer)
{
unsigned int i;
-
+
HB_GSUB gsub = NULL;
-
+
g_return_if_fail (PANGO_IS_OT_RULESET (ruleset));
g_return_if_fail (PANGO_IS_OT_INFO (ruleset->info));
PangoOTBuffer *buffer)
{
unsigned int i;
-
+
HB_GPOS gpos = NULL;
-
+
g_return_if_fail (PANGO_IS_OT_RULESET (ruleset));
g_return_if_fail (PANGO_IS_OT_INFO (ruleset->info));
typedef struct _PangoOTGlyph PangoOTGlyph;
typedef struct _PangoOTRuleset PangoOTRuleset;
-typedef enum
+typedef enum
{
PANGO_OT_TABLE_GSUB,
PANGO_OT_TABLE_GPOS
* pango-renderer.h: Base class for rendering
*
* Copyright (C) 2004 Red Hat, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
{
PangoUnderline underline;
PangoRectangle underline_rect;
-
+
gboolean strikethrough;
PangoRectangle strikethrough_rect;
pango_renderer_class_init (PangoRendererClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
+
klass->draw_glyphs = pango_renderer_default_draw_glyphs;
klass->draw_rectangle = pango_renderer_default_draw_rectangle;
klass->draw_error_underline = pango_renderer_default_draw_error_underline;
pango_renderer_finalize (GObject *gobject)
{
PangoRenderer *renderer = PANGO_RENDERER (gobject);
-
+
if (renderer->matrix)
pango_matrix_free (renderer->matrix);
}
int y)
{
PangoLayoutIter *iter;
-
+
g_return_if_fail (PANGO_IS_RENDERER (renderer));
g_return_if_fail (PANGO_IS_LAYOUT (layout));
pango_renderer_set_matrix (renderer,
pango_context_get_matrix (context));
}
-
+
pango_renderer_activate (renderer);
iter = pango_layout_get_iter (layout);
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
-
+
line = pango_layout_iter_get_line_readonly (iter);
-
+
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
while (pango_layout_iter_next_line (iter));
pango_layout_iter_free (iter);
-
+
pango_renderer_deactivate (renderer);
}
{
PangoRectangle *rect = &state->underline_rect;
PangoUnderline underline = state->underline;
-
+
state->underline = PANGO_UNDERLINE_NONE;
-
+
switch (underline)
{
case PANGO_UNDERLINE_NONE:
gboolean strikethrough = state->strikethrough;
state->strikethrough = FALSE;
-
+
if (strikethrough)
pango_renderer_draw_rectangle (renderer,
PANGO_RENDER_PART_STRIKETHROUGH,
LineState *state = renderer->priv->line_state;
if (!state)
return;
-
+
if (part == PANGO_RENDER_PART_UNDERLINE &&
state->underline != PANGO_UNDERLINE_NONE)
{
PangoRectangle *rect = &state->underline_rect;
-
+
rect->width = state->logical_rect_end - rect->x;
draw_underline (renderer, state);
state->underline = renderer->underline;
{
PangoRectangle *current_rect = &state->underline_rect;
PangoRectangle new_rect;
-
+
int underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
int underline_position = pango_font_metrics_get_underline_position (metrics);
new_rect.width = logical_rect->width;
new_rect.height = underline_thickness;
new_rect.y = base_y;
-
+
switch (renderer->underline)
{
case PANGO_UNDERLINE_NONE:
new_rect.y += ink_rect->y + ink_rect->height + underline_thickness;
break;
}
-
+
if (renderer->underline == state->underline &&
new_rect.y == current_rect->y &&
new_rect.height == current_rect->height)
else
{
draw_underline (renderer, state);
-
+
*current_rect = new_rect;
state->underline = renderer->underline;
}
{
PangoRectangle *current_rect = &state->strikethrough_rect;
PangoRectangle new_rect;
-
+
int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);
-
+
new_rect.x = base_x + logical_rect->x;
new_rect.width = logical_rect->width;
new_rect.y = base_y - strikethrough_position;
new_rect.height = strikethrough_thickness;
-
+
if (state->strikethrough &&
new_rect.y == current_rect->y &&
new_rect.height == current_rect->height)
else
{
draw_strikethrough (renderer, state);
-
+
*current_rect = new_rect;
state->strikethrough = TRUE;
}
GSList *l;
gboolean got_overall = FALSE;
PangoRectangle overall_rect;
-
+
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
/* We only change the matrix if the renderer isn't already
logical = &logical_rect;
pango_renderer_prepare_run (renderer, run);
-
+
get_item_properties (run->item, &rise, &shape_attr);
if (shape_attr)
pango_layout_line_get_extents (line, NULL, &overall_rect);
got_overall = TRUE;
}
-
+
pango_renderer_draw_rectangle (renderer,
PANGO_RENDER_PART_BACKGROUND,
x + x_off,
{
metrics = pango_font_get_metrics (run->item->analysis.font,
run->item->analysis.language);
-
+
if (renderer->underline != PANGO_UNDERLINE_NONE)
add_underline (renderer, &state,metrics,
x + x_off, y - rise,
ink, logical);
-
+
if (renderer->strikethrough)
add_strikethrough (renderer, &state, metrics,
x + x_off, y - rise,
ink, logical);
-
+
pango_font_metrics_unref (metrics);
}
draw_strikethrough (renderer, &state);
renderer->priv->line_state = NULL;
-
+
pango_renderer_deactivate (renderer);
}
int y)
{
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
-
+
pango_renderer_activate (renderer);
PANGO_RENDERER_GET_CLASS (renderer)->draw_glyphs (renderer, font, glyphs, x, y);
-
+
pango_renderer_deactivate (renderer);
}
{
PangoGlyphInfo *gi = &glyphs->glyphs[i];
Point p;
-
+
to_device (renderer->matrix,
x + x_position + gi->geometry.x_offset,
y + gi->geometry.y_offset,
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
g_return_if_fail (IS_VALID_PART (part));
g_return_if_fail (renderer->active_count > 0);
-
+
PANGO_RENDERER_GET_CLASS (renderer)->draw_rectangle (renderer, part, x, y, width, height);
}
points[1].y, points[1].x, points[1].x + base_width,
points[2].y, points[2].x - base_width, points[2].x);
pango_renderer_draw_trapezoid (renderer, part, /* C */
- points[2].y, points[2].x - base_width, points[2].x,
+ points[2].y, points[2].x - base_width, points[2].x,
points[3].y, points[3].x, points[3].x);
}
else
points[1].y, points[1].x - base_width, points[1].x,
points[2].y, points[2].x, points[2].x + base_width);
pango_renderer_draw_trapezoid (renderer, part, /* C */
- points[2].y, points[2].x, points[2].x + base_width,
+ points[2].y, points[2].x, points[2].x + base_width,
points[3].y, points[3].x, points[3].x);
}
}
{
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
g_return_if_fail (renderer->active_count > 0);
-
+
PANGO_RENDERER_GET_CLASS (renderer)->draw_error_underline (renderer, x, y, width, height);
}
* / \ / \ / \ / \ / \ |
* \ \ /\ \ / / \ \ /\ \ |
* \ \/B \ \/ C / \ \/B \ \ | height = HEIGHT_SQUARES * square
- * \ A \ /\ A \ / \ A \ /\ A \ |
+ * \ A \ /\ A \ / \ A \ /\ A \ |
* \ \/ \ \/ \ \/ \ \ |
* \ / \ / \ / \ / |
* \/ \/ \/ \/ -
* are axis aligned rectangles. (If fonts were square, the diagrams
* would be clearer)
*
- * (0,0)
- * /\ /\
- * / \ / \
- * /\ /\ /\ /
- * / \/ \/ \/
- * / \ /\ /
- * Y axis \/ \/
- * \ /\
- * \/ \
+ * (0,0)
+ * /\ /\
+ * / \ / \
+ * /\ /\ /\ /
+ * / \/ \/ \/
+ * / \ /\ /
+ * Y axis \/ \/
+ * \ /\
+ * \/ \
* \ X axis
*
* Note that the long side in this coordinate system is HEIGHT_SQUARES + 1
* either HEIGHT_SQUARES=3 (a little long and skinny) or
* HEIGHT_SQUARES=2 (a bit short and stubby)
*/
-
+
#define HEIGHT_SQUARES 2.5
static void
* @y2: Y coordinate of bottom of trapezoid
* @x12: X coordinate of left end of bottom of trapezoid
* @x22: X coordinate of right end of bottom of trapezoid
- *
+ *
* Draws a trapezoid with the parallel sides aligned with the X axis
* using the given #PangoRenderer; coordinates are in device space.
*
{
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
g_return_if_fail (renderer->active_count > 0);
-
+
if (PANGO_RENDERER_GET_CLASS (renderer)->draw_trapezoid)
PANGO_RENDERER_GET_CLASS (renderer)->draw_trapezoid (renderer, part,
y1_, x11, x21,
* @glyph: the glyph index of a single glyph
* @x: X coordinate of left edge of baseline of glyph
* @y: Y coordinate of left edge of baseline of glyph
- *
+ *
* Draws a single glyph with coordinates in device space.
*
* Since: 1.8
{
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
g_return_if_fail (renderer->active_count > 0);
-
+
if (glyph == PANGO_GLYPH_EMPTY) /* glyph PANGO_GLYPH_EMPTY never renders */
return;
-
+
if (PANGO_RENDERER_GET_CLASS (renderer)->draw_glyph)
PANGO_RENDERER_GET_CLASS (renderer)->draw_glyph (renderer, font, glyph, x, y);
}
/**
* pango_renderer_activate:
* @renderer: a #PangoRenderer
- *
+ *
* Does initial setup before rendering operations on @renderer.
* pango_renderer_deactivate() should be called when done drawing.
* Calls such as pango_renderer_draw_layout() automatically
/**
* pango_renderer_deactivate:
* @renderer: a #PangoRenderer
- *
+ *
* Cleans up after rendering operations on @renderer. See
* docs for pango_renderer_activate().
*
{
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
g_return_if_fail (renderer->active_count > 0);
-
+
if (renderer->active_count == 1)
{
if (PANGO_RENDERER_GET_CLASS (renderer)->end)
* @renderer: a #PangoRenderer
* @part: the part to change the color of
* @color: the new color or %NULL to unset the current color
- *
+ *
* Sets the color for part of the rendering.
*
* Since: 1.8
return;
pango_renderer_part_changed (renderer, part);
-
+
if (color)
{
renderer->priv->color_set[part] = TRUE;
* pango_renderer_get_color:
* @renderer: a #PangoRenderer
* @part: the part to get the color for
- *
+ *
* Gets the current rendering color for the specified part.
- *
+ *
* Return value: the color for the specified part, or %NULL
* if it hasn't been set and should be inherited from the
* environment.
{
g_return_val_if_fail (PANGO_IS_RENDERER_FAST (renderer), NULL);
g_return_val_if_fail (IS_VALID_PART (part), NULL);
-
+
if (renderer->priv->color_set[part])
return &renderer->priv->color[part];
else
* pango_renderer_part_changed:
* @renderer: a #PangoRenderer
* @part: the part for which rendering has changed.
- *
+ *
* Informs Pango that the way that the rendering is done
* for @part has changed in a way that would prevent multiple
* pieces being joined together into one drawing call. For
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
g_return_if_fail (IS_VALID_PART (part));
g_return_if_fail (renderer->active_count > 0);
-
+
handle_line_state_change (renderer, part);
if (PANGO_RENDERER_GET_CLASS (renderer)->part_changed)
* pango_renderer_prepare_run:
* @renderer: a #PangoRenderer
* @run: a #PangoLayoutRun
- *
+ *
* Set up the state of the #PangoRenderer for rendering @run.
*
* Since: 1.8
PangoLayoutRun *run)
{
g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));
-
+
PANGO_RENDERER_GET_CLASS (renderer)->prepare_run (renderer, run);
}
for (l = run->item->analysis.extra_attrs; l; l = l->next)
{
PangoAttribute *attr = l->data;
-
+
switch (attr->klass->type)
{
case PANGO_ATTR_UNDERLINE:
renderer->underline = ((PangoAttrInt *)attr)->value;
break;
-
+
case PANGO_ATTR_STRIKETHROUGH:
renderer->strikethrough = ((PangoAttrInt *)attr)->value;
break;
-
+
case PANGO_ATTR_FOREGROUND:
fg_color = &((PangoAttrColor *)attr)->color;
break;
-
+
case PANGO_ATTR_BACKGROUND:
bg_color = &((PangoAttrColor *)attr)->color;
break;
-
+
case PANGO_ATTR_UNDERLINE_COLOR:
underline_color = &((PangoAttrColor *)attr)->color;
break;
-
+
case PANGO_ATTR_STRIKETHROUGH_COLOR:
strikethrough_color = &((PangoAttrColor *)attr)->color;
break;
-
+
default:
break;
}
* @renderer: a #PangoRenderer
* @matrix: a #PangoMatrix, or %NULL to unset any existing matrix.
* (No matrix set is the same as setting the identity matrix.)
- *
+ *
* Sets the transformation matrix that will be applied when rendering.
*
* Since: 1.8
* pango-renderer.h: Base class for rendering
*
* Copyright (C) 2004, Red Hat, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
PangoUnderline underline;
gboolean strikethrough;
int active_count;
-
+
/*< public >*/
PangoMatrix *matrix; /* May be NULL */
-
+
/*< private >*/
PangoRendererPrivate *priv;
};
* @draw_rectangle: draws a rectangle
* @draw_error_underline: draws a squiggly line that approximately
* covers the given rectangle in the style of an underline used to
- * indicate a spelling error.
+ * indicate a spelling error.
* @draw_shape: draw content for a glyph shaped with #PangoAttrShape.
* @x, @y are the coordinates of the left edge of the baseline,
* in user coordinates.
PangoLayoutRun *run);
/*< private >*/
-
+
/* Padding for future expansion */
void (*_pango_reserved1) (void);
void (*_pango_reserved2) (void);
gunichar start;
guint16 chars;
guint16 script;
-} pango_script_table[] = {
+} pango_script_table[] = {
{ 0x2000, 12, PANGO_SCRIPT_COMMON },
{ 0x200c, 2, PANGO_SCRIPT_INHERITED },
{ 0x200e, 86, PANGO_SCRIPT_COMMON },
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
+ *
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
int mid = saved_mid;
- do
+ do
{
if (ch < pango_script_table[mid].start)
upper = mid - 1;
/**
* pango_script_for_unichar:
* @ch: a Unicode character
- *
+ *
* Looks up the #PangoScript for a particular character (as defined by
* Unicode Standard Annex #24). No check is made for @ch being a
* valid Unicode character; if you pass in invalid character, the
* result is undefined.
- *
+ *
* Return value: the #PangoScript for the character.
*
* Since: 1.4
{
if (ch < G_N_ELEMENTS (pango_script_easy_table))
return pango_script_easy_table[ch];
- else
- return pango_script_for_unichar_bsearch (ch);
+ else
+ return pango_script_for_unichar_bsearch (ch);
}
/**********************************************************************/
* pango_script_iter_new:
* @text: a UTF-8 string
* @length: length of @text, or -1 if @text is nul-terminated.
- *
+ *
* Create a new #PangoScriptIter, used to break a string of
* Unicode into runs by text. No copy is made of @text, so
* the caller needs to make sure it remains valid until
* the iterator is freed with pango_script_iter_free ().x
- *
+ *
* Return value: the new script iterator, initialized
* to point at the first range in the text, which should be
* freed with pango_script_iter_free(). If the string is
iter->script_start = text;
iter->script_end = text;
iter->script_code = PANGO_SCRIPT_COMMON;
-
+
iter->paren_sp = -1;
pango_script_iter_next (iter);
/**
* pango_script_iter_free:
* @iter: a #PangoScriptIter
- *
+ *
* Frees a #PangoScriptIter created with pango_script_iter_new().
*
* Since: 1.4
* @start: location to store start position of the range, or %NULL
* @end: location to store end position of the range, or %NULL
* @script: location to store script for range, or %NULL
- *
+ *
* Gets information about the range to which @iter currently points.
* The range is the set of locations p where *start <= p < *end.
* (That is, it doesn't include the character stored at *end)
while (lower <= upper)
{
int mid = (lower + upper) / 2;
-
+
if (ch < paired_chars[mid])
upper = mid - 1;
else if (ch > paired_chars[mid])
/**
* pango_script_iter_next:
* @iter: a #PangoScriptIter
- *
+ *
* Advances a #PangoScriptIter to the next range. If @iter
* is already at the end, it is left unchanged and %FALSE
* is returned.
- *
+ *
* Return value: %TRUE if @iter was successfully advanced.
*
* Since: 1.4
pango_script_iter_next (PangoScriptIter *iter)
{
int start_sp;
-
+
if (iter->script_end == iter->text_end)
return FALSE;
gunichar ch = g_utf8_get_char (iter->script_end);
PangoScript sc;
int pair_index;
-
+
sc = pango_script_for_unichar (ch);
if (sc != PANGO_SCRIPT_COMMON)
pair_index = -1;
if (pair_index >= 0 && !IS_OPEN (pair_index) && iter->paren_sp >= 0)
{
iter->paren_sp--;
-
+
if (iter->paren_sp < start_sp)
start_sp = iter->paren_sp;
}
* pango_language_includes_script:
* @language: a #PangoLanguage
* @script: a #PangoScript
- *
+ *
* Determines if @script is one of the scripts used to
* write @language. The returned value is conservative;
* if nothing is known about the language tag @language,
* determining if a supplied language tag is relevant to
* a particular section of text. It probably is not useful for
* applications in most circumstances.
- *
+ *
* Return value: %TRUE if @script is one of the scripts used
* to write @language, or if nothing is known about @language.
*
/**
* pango_script_get_sample_language:
* @script: a #PangoScript
- *
+ *
* Given a script, finds a language tag that is reasonably
* representative of that script. This will usually be the
* most widely spoken or used language written in that script:
* significantly different sets of Han characters and forms
* of shared characters. No sample language can be provided
* for many historical scripts as well.
- *
+ *
* Return value: a #PangoLanguage that is representative
* of the script, or %NULL if no such language exists.
*
"", /* PANGO_SCRIPT_LINEAR_B */
"", /* PANGO_SCRIPT_TAI_LE */
"uga", /* PANGO_SCRIPT_UGARITIC */
-
+
"", /* PANGO_SCRIPT_NEW_TAI_LUE */
"bug", /* PANGO_SCRIPT_BUGINESE */
/* The original script for Old Church Slavonic (chu), later
"nqo" /* PANGO_SCRIPT_NKO */
};
const char *sample_language;
-
+
g_return_val_if_fail (script >= 0, NULL);
g_return_val_if_fail ((guint)script < G_N_ELEMENTS (sample_languages), NULL);
-
+
sample_language = sample_languages[script];
if (!sample_language[0])
PANGO_SCRIPT_LINEAR_B, /* Linb */
PANGO_SCRIPT_TAI_LE, /* Tale */
PANGO_SCRIPT_UGARITIC, /* Ugar */
-
+
/* Unicode-4.1 additions */
PANGO_SCRIPT_NEW_TAI_LUE, /* Talu */
PANGO_SCRIPT_BUGINESE, /* Bugi */
* pango_tab_array_new:
* @initial_size: Initial number of tab stops to allocate, can be 0
* @positions_in_pixels: whether positions are in pixel units
- *
+ *
* Creates an array of @initial_size tab stops. Tab stops are specified in
* pixel units if @positions_in_pixels is %TRUE, otherwise in Pango
* units. All stops are initially at position 0.
- *
+ *
* Return value: the newly allocated #PangoTabArray, which should
* be freed with pango_tab_array_free().
**/
array->tabs = NULL;
array->positions_in_pixels = positions_in_pixels;
-
+
return array;
}
* @first_alignment: alignment of first tab stop
* @first_position: position of first tab stop
* @varargs: additional alignment/position pairs
- *
+ *
* This is a convenience function that creates a #PangoTabArray
* and allows you to specify the alignment and position of each
* tab stop. You <emphasis>must</emphasis> provide an alignment
* and position for @size tab stops.
- *
+ *
* Return value: the newly allocated #PangoTabArray, which should
* be freed with pango_tab_array_free().
**/
int i;
g_return_val_if_fail (size >= 0, NULL);
-
+
array = pango_tab_array_new (size, positions_in_pixels);
if (size == 0)
if (size == 1)
return array;
-
+
va_start (args, first_position);
i = 1;
pango_tab_array_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoTabArray"),
(GBoxedCopyFunc)pango_tab_array_copy,
/**
* pango_tab_array_copy:
* @src: #PangoTabArray to copy
- *
+ *
* Copies a #PangoTabArray
- *
+ *
* Return value: the newly allocated #PangoTabArray, which should
* be freed with pango_tab_array_free().
**/
PangoTabArray *copy;
g_return_val_if_fail (src != NULL, NULL);
-
+
copy = pango_tab_array_new (src->size, src->positions_in_pixels);
memcpy (copy->tabs, src->tabs, sizeof(PangoTab)*src->size);
* @tab_array: a #PangoTabArray
*
* Frees a tab array and associated resources.
- *
+ *
**/
void
pango_tab_array_free (PangoTabArray *tab_array)
g_return_if_fail (tab_array != NULL);
g_free (tab_array->tabs);
-
+
g_slice_free (PangoTabArray, tab_array);
}
/**
* pango_tab_array_get_size:
* @tab_array: a #PangoTabArray
- *
+ *
* Gets the number of tab stops in @tab_array.
- *
+ *
* Return value: the number of tab stops in the array.
**/
gint
pango_tab_array_get_size (PangoTabArray *tab_array)
{
g_return_val_if_fail (tab_array != NULL, 0);
-
+
return tab_array->size;
}
* pango_tab_array_resize:
* @tab_array: a #PangoTabArray
* @new_size: new size of the array
- *
+ *
* Resizes a tab array. You must subsequently initialize any tabs that
* were added as a result of growing the array.
*
if (new_size > tab_array->allocated)
{
gint current_end = tab_array->allocated;
-
+
/* Ratchet allocated size up above the index. */
if (tab_array->allocated == 0)
tab_array->allocated = 2;
-
+
while (new_size > tab_array->allocated)
tab_array->allocated = tab_array->allocated * 2;
-
+
tab_array->tabs = g_renew (PangoTab, tab_array->tabs,
tab_array->allocated);
-
+
init_tabs (tab_array, current_end, tab_array->allocated);
}
-
+
tab_array->size = new_size;
}
* Sets the alignment and location of a tab stop.
* @alignment must always be #PANGO_TAB_LEFT in the current
* implementation.
- *
+ *
**/
void
pango_tab_array_set_tab (PangoTabArray *tab_array,
if (tab_index >= tab_array->size)
pango_tab_array_resize (tab_array, tab_index + 1);
-
+
tab_array->tabs[tab_index].alignment = alignment;
tab_array->tabs[tab_index].location = location;
}
* @location: location to store tab position, or %NULL
*
* Gets the alignment and position of a tab stop.
- *
+ *
**/
void
pango_tab_array_get_tab (PangoTabArray *tab_array,
* If non-%NULL, @alignments and @locations are filled with allocated
* arrays of length pango_tab_array_get_size(). You must free the
* returned array.
- *
+ *
**/
void
pango_tab_array_get_tabs (PangoTabArray *tab_array,
gint **locations)
{
gint i;
-
+
g_return_if_fail (tab_array != NULL);
if (alignments)
if (locations)
*locations = g_new (gint, tab_array->size);
-
+
i = 0;
while (i < tab_array->size)
{
/**
* pango_tab_array_get_positions_in_pixels:
* @tab_array: a #PangoTabArray
- *
+ *
* Returns %TRUE if the tab positions are in pixels, %FALSE if they are
* in Pango units.
- *
+ *
* Return value: whether positions are in pixels.
**/
gboolean
pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array)
{
g_return_val_if_fail (tab_array != NULL, FALSE);
-
+
return tab_array->positions_in_pixels;
}
* @PANGO_DIRECTION_WEAK_LTR: A weak left-to-right direction
* @PANGO_DIRECTION_WEAK_RTL: A weak right-to-left direction
* @PANGO_DIRECTION_NEUTRAL: No direction specified
- *
+ *
* The #PangoDirection type represents a direction in the
* Unicode bidirectional algorithm; not every value in this
* enumeration makes sense for every usage of #PangoDirection;
* enumeration as the writing direction of a block of
* text and are no longer used; See #PangoGravity for how
* vertical text is handled in Pango.
- **/
+ **/
typedef enum {
PANGO_DIRECTION_LTR,
PANGO_DIRECTION_RTL,
/**
* pango_trim_string:
* @str: a string
- *
+ *
* Trims leading and trailing whitespace from a string.
- *
+ *
* Return value: A newly-allocated string that must be freed with g_free()
**/
char *
int len;
g_return_val_if_fail (str != NULL, NULL);
-
+
while (*str && g_ascii_isspace (*str))
str++;
/**
* pango_split_file_list:
* @str: a %G_SEARCHPATH_SEPARATOR separated list of filenames
- *
+ *
* Splits a %G_SEARCHPATH_SEPARATOR-separated list of files, stripping
* white space and substituting ~/ with $HOME/.
- *
+ *
* Return value: a list of strings to be freed with g_strfreev()
**/
char **
{
g_free(file);
g_free (files[i]);
-
+
for (j = i + 1; files[j]; j++)
files[j - 1] = files[j];
-
+
files[j - 1] = NULL;
continue;
#endif
g_free (files[i]);
files[i] = file;
-
+
i++;
}
* pango_read_line:
* @stream: a stdio stream
* @str: #GString buffer into which to write the result
- *
+ *
* Reads an entire line from a file into a buffer. Lines may
* be delimited with '\n', '\r', '\n\r', or '\r\n'. The delimiter
* is not written into the buffer. Text after a '#' character is treated as
* '\' proceeding a line delimiter combines adjacent lines. A '\' proceeding
* any other character is ignored and written into the output buffer
* unmodified.
- *
+ *
* Return value: 0 if the stream was already at an %EOF character, otherwise
* the number of lines read (this is useful for maintaining
- * a line number counter which doesn't combine lines with '\')
+ * a line number counter which doesn't combine lines with '\')
**/
gint
pango_read_line (FILE *stream, GString *str)
gboolean comment = FALSE;
int n_read = 0;
int lines = 1;
-
+
flockfile (stream);
g_string_truncate (str, 0);
-
+
while (1)
{
int c;
-
+
c = getc_unlocked (stream);
if (c == EOF)
{
if (quoted)
g_string_append_c (str, '\\');
-
+
goto done;
}
else
if (quoted)
{
quoted = FALSE;
-
+
switch (c)
{
case '#':
ungetc (next_c, stream);
lines++;
-
+
break;
}
default:
- g_string_append_c (str, '\\');
+ g_string_append_c (str, '\\');
g_string_append_c (str, c);
}
}
/**
* pango_skip_space:
* @pos: in/out string position
- *
+ *
* Skips 0 or more characters of white space.
- *
+ *
* Return value: %FALSE if skipping the white space leaves
* the position at a '\0' character.
**/
pango_skip_space (const char **pos)
{
const char *p = *pos;
-
+
while (g_ascii_isspace (*p))
p++;
* pango_scan_word:
* @pos: in/out string position
* @out: a #GString into which to write the result
- *
+ *
* Scans a word into a #GString buffer. A word consists
* of [A-Za-z_] followed by zero or more [A-Za-z_0-9]
* Leading white space is skipped.
- *
- * Return value: %FALSE if a parse error occurred.
+ *
+ * Return value: %FALSE if a parse error occurred.
**/
gboolean
pango_scan_word (const char **pos, GString *out)
while (g_ascii_isspace (*p))
p++;
-
+
if (!((*p >= 'A' && *p <= 'Z') ||
(*p >= 'a' && *p <= 'z') ||
*p == '_'))
* pango_scan_string:
* @pos: in/out string position
* @out: a #GString into which to write the result
- *
+ *
* Scans a string into a #GString buffer. The string may either
* be a sequence of non-white-space characters, or a quoted
* string with '"'. Instead a quoted string, '\"' represents
* a literal quote. Leading white space outside of quotes is skipped.
- *
+ *
* Return value: %FALSE if a parse error occurred.
**/
gboolean
pango_scan_string (const char **pos, GString *out)
{
const char *p = *pos;
-
+
while (g_ascii_isspace (*p))
p++;
if (quoted)
{
int c = *p;
-
+
switch (c)
{
case '\0':
default:
break;
}
-
+
quoted = FALSE;
g_string_append_c (out, c);
}
* pango_scan_int:
* @pos: in/out string position
* @out: an int into which to write the result
- *
- * Scans an integer.
+ *
+ * Scans an integer.
* Leading white space is skipped.
- *
+ *
* Return value: %FALSE if a parse error occurred.
**/
gboolean
errno = 0;
return FALSE;
}
-
+
*out = (int)temp;
if ((long)(*out) != temp)
{
gchar **groups;
gsize groups_count = 0;
guint group_index;
-
+
if (!g_key_file_load_from_file(key_file,filename, 0, &key_file_error))
{
if (key_file_error)
g_key_file_free(key_file);
return;
}
-
+
groups = g_key_file_get_groups (key_file, &groups_count);
for (group_index = 0; group_index < groups_count; group_index++)
{
const gchar *group = groups[group_index];
GError *keys_error = NULL;
gchar **keys;
-
+
keys = g_key_file_get_keys(key_file, group, &keys_count, &keys_error);
-
+
if (keys)
{
guint key_index;
char *filename;
const char *home;
const char *envvar;
-
+
config_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_free);
/**
* pango_config_key_get:
* @key: Key to look up, in the form "SECTION/KEY".
- *
+ *
* Looks up a key in the Pango config database
* (pseudo-win.ini style, read from $sysconfdir/pango/pangorc,
* ~/.pangorc, and getenv (PANGO_RC_FILE).)
- *
+ *
* Return value: the value, if found, otherwise %NULL. The value is a
* newly-allocated string and must be freed with g_free().
**/
pango_config_key_get (const char *key)
{
g_return_val_if_fail (key != NULL, NULL);
-
+
read_config ();
return g_strdup (g_hash_table_lookup (config_hash, key));
* the DLL's location, or stored in the Registry).
*
* Return value: the Pango sysconf directory. The returned string should
- * not be freed.
+ * not be freed.
*/
G_CONST_RETURN char *
pango_get_sysconf_subdirectory (void)
* not be freed.
*
* Return value: the Pango lib directory. The returned string should
- * not be freed.
+ * not be freed.
*/
G_CONST_RETURN char *
pango_get_lib_subdirectory (void)
* @value: integer to store the result in, or %NULL.
* @warn: if %TRUE, issue a g_warning() on bad input.
* @possible_values: place to store list of possible values on failure, or %NULL.
- *
+ *
* Parses an enum type and stored the result in @value.
*
* If @str does not match the nick name of any of the possible values for the
* @possible_values. The list is slash-separated, eg.
* "none/start/middle/end". If failed and @possible_values is not %NULL,
* returned string should be freed using g_free().
- *
+ *
* Return value: %TRUE if @str was successfully parsed.
*
* Since: 1.16
- **/
+ **/
gboolean
pango_parse_enum (GType type,
const char *str,
if (possible_values)
*possible_values = s->str;
-
+
g_string_free (s, possible_values ? FALSE : TRUE);
}
}
* @str: a string to parse.
* @style: a #PangoStyle to store the result in.
* @warn: if %TRUE, issue a g_warning() on bad input.
- *
+ *
* Parses a font style. The allowed values are "normal",
* "italic" and "oblique", case variations being
* ignored.
- *
+ *
* Return value: %TRUE if @str was successfully parsed.
- **/
+ **/
gboolean
pango_parse_style (const char *str,
PangoStyle *style,
}
if (warn)
g_warning ("style must be normal, italic, or oblique");
-
+
return FALSE;
}
* @str: a string to parse.
* @variant: a #PangoVariant to store the result in.
* @warn: if %TRUE, issue a g_warning() on bad input.
- *
+ *
* Parses a font variant. The allowed values are "normal"
* and "smallcaps" or "small_caps", case variations being
* ignored.
- *
+ *
* Return value: %TRUE if @str was successfully parsed.
- **/
+ **/
gboolean
pango_parse_variant (const char *str,
PangoVariant *variant,
}
break;
}
-
+
if (warn)
g_warning ("variant must be normal or small_caps");
return FALSE;
* @str: a string to parse.
* @weight: a #PangoWeight to store the result in.
* @warn: if %TRUE, issue a g_warning() on bad input.
- *
+ *
* Parses a font weight. The allowed values are "heavy",
- * "ultrabold", "bold", "normal", "light", "ultraleight"
+ * "ultrabold", "bold", "normal", "light", "ultraleight"
* and integers. Case variations are ignored.
- *
+ *
* Return value: %TRUE if @str was successfully parsed.
- **/
+ **/
gboolean
pango_parse_weight (const char *str,
PangoWeight *weight,
return TRUE;
}
}
-
+
if (warn)
g_warning ("weight must be ultralight, light, normal, bold, ultrabold, heavy, or an integer");
return FALSE;
* @str: a string to parse.
* @stretch: a #PangoStretch to store the result in.
* @warn: if %TRUE, issue a g_warning() on bad input.
- *
- * Parses a font stretch. The allowed values are
- * "ultra_condensed", "extra_condensed", "condensed",
- * "semi_condensed", "normal", "semi_expanded", "expanded",
- * "extra_expanded" and "ultra_expanded". Case variations are
+ *
+ * Parses a font stretch. The allowed values are
+ * "ultra_condensed", "extra_condensed", "condensed",
+ * "semi_condensed", "normal", "semi_expanded", "expanded",
+ * "extra_expanded" and "ultra_expanded". Case variations are
* ignored and the '_' characters may be omitted.
- *
+ *
* Return value: %TRUE if @str was successfully parsed.
- **/
+ **/
gboolean
pango_parse_stretch (const char *str,
PangoStretch *stretch,
return FALSE;
switch (str[0])
- {
+ {
case 'c':
case 'C':
if (g_ascii_strcasecmp (str, "condensed") == 0)
}
static const char canon_map[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
};
-
+
static gboolean
lang_equal (gconstpointer v1,
gconstpointer v2)
pango_language_get_type (void)
{
static GType our_type = 0;
-
+
if (our_type == 0)
our_type = g_boxed_type_register_static (I_("PangoLanguage"),
(GBoxedCopyFunc)pango_language_copy,
* COUNTRY is an ISO-3166 country code. For instance, sv_FI for
* Swedish as written in Finland or pt_BR for Portuguese as written in
* Brazil.
- *
+ *
* On Windows, the C library doesn't use any such environment
* variables, and setting them won't affect the behavior of functions
- * like ctime(). The user sets the locale through the Regional Options
- * in the Control Panel. The C library (in the setlocale() function)
- * does not use country and language codes, but country and language
- * names spelled out in English.
+ * like ctime(). The user sets the locale through the Regional Options
+ * in the Control Panel. The C library (in the setlocale() function)
+ * does not use country and language codes, but country and language
+ * names spelled out in English.
* However, this function does check the above environment
* variables, and does return a Unix-style locale string based on
* either said environment variables or the thread's current locale.
* COUNTRY is an ISO-3166 country code. For instance, sv_FI for
* Swedish as written in Finland or pt_BR for Portuguese as written in
* Brazil.
- *
+ *
* On Windows, the C library does not use any such environment
* variables, and setting them won't affect the behavior of functions
- * like ctime(). The user sets the locale through the Regional Options
- * in the Control Panel. The C library (in the setlocale() function)
- * does not use country and language codes, but country and language
- * names spelled out in English.
+ * like ctime(). The user sets the locale through the Regional Options
+ * in the Control Panel. The C library (in the setlocale() function)
+ * does not use country and language codes, but country and language
+ * names spelled out in English.
* However, this function does check the above environment
* variables, and does return a Unix-style locale string based on
* either said environment variables or the thread's current locale.
* for the user settings to take effect. Gtk+ does this in its initialization
* functions automatically (by calling gtk_set_locale()).
* See <literal>man setlocale</literal> for more details.
- *
+ *
* Return value: the default language as a #PangoLanguage, must not be
* freed.
*
pango_language_get_default (void)
{
gchar *lang;
- PangoLanguage *result;
-
+ PangoLanguage *result;
+
lang = _pango_get_lc_ctype ();
-
+
result = pango_language_from_string (lang);
g_free (lang);
-
+
return result;
}
/**
* pango_language_from_string:
* @language: a string representing a language tag
- *
+ *
* Take a RFC-3066 format language tag as a string and convert it to a
* #PangoLanguage pointer that can be efficiently copied (copy the
* pointer) and compared with other language tags (compare the
*
* Use pango_language_get_default() if you want to get the #PangoLanguage for
* the current locale of the process.
- *
+ *
* Return value: an opaque pointer to a #PangoLanguage structure.
* this will be valid forever after.
**/
* ',', or space characters.
* Each element must either be '*', or a RFC 3066 language range
* canonicalized as by pango_language_from_string()
- *
+ *
* Checks if a language tag matches one of the elements in a list of
* language ranges. A language tag is considered to match a range
* in the list if the range is '*', the range is exactly the tag,
/**
* pango_language_get_sample_string:
* @language: a #PangoLanguage
- *
+ *
* Get a string that is representative of the characters needed to
* render a particular language. This function is a bad hack for
* internal use by renderers and Pango.
- *
+ *
* Return value: the sample string. This value is owned by Pango
* and must not be freed.
**/
pango_language_get_sample_string (PangoLanguage *language)
{
const char *result;
-
+
if (language)
{
const char *lang_str = pango_language_to_string (language);
-
+
LangInfo *lang_info = bsearch (lang_str, lang_texts,
G_N_ELEMENTS (lang_texts), sizeof (LangInfo),
lang_info_compare);
*
* Use g_unichar_get_mirror_char() instead; the docs for that function
* provide full details.
- *
+ *
* Return value: %TRUE if @ch has a mirrored character and @mirrored_ch is
* filled in, %FALSE otherwise
**/
-gboolean
+gboolean
pango_get_mirror_char (gunichar ch,
gunichar *mirrored_ch)
{
- return g_unichar_get_mirror_char (ch, mirrored_ch);
+ return g_unichar_get_mirror_char (ch, mirrored_ch);
}
g_free (alias->families[i]);
g_free (alias->families);
-
+
g_slice_free (struct PangoAlias, alias);
}
read_alias_file (const char *filename)
{
FILE *file;
-
+
GString *line_buffer;
GString *tmp_buffer1;
GString *tmp_buffer2;
pos = line_buffer->str;
if (!pango_skip_space (&pos))
continue;
-
+
if (!pango_scan_word (&pos, tmp_buffer1) ||
!pango_skip_space (&pos))
{
errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
goto error;
}
-
+
if (*pos == '+')
{
append = TRUE;
errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
goto error;
}
-
+
if (!pango_scan_string (&pos, tmp_buffer2))
{
errstring = g_strdup ("Error parsing value string");
}
alias_key.alias = g_ascii_strdown (tmp_buffer1->str, -1);
-
+
/* Remove any existing values */
alias = g_hash_table_lookup (pango_aliases_ht, &alias_key);
-
+
if (!alias)
{
alias = g_slice_new0 (struct PangoAlias);
alias->alias = alias_key.alias;
-
+
g_hash_table_insert (pango_aliases_ht,
alias, alias);
}
else
g_free (alias_key.alias);
-
+
new_families = g_strsplit (tmp_buffer2->str, ",", -1);
-
+
n_new = 0;
while (new_families[n_new])
n_new++;
-
+
if (alias->families && append)
{
alias->families = g_realloc (alias->families,
for (i = 0; i < alias->n_families; i++)
g_free (alias->families[i]);
g_free (alias->families);
-
+
alias->families = new_families;
alias->n_families = n_new;
}
if (ferror (file))
errstring = g_strdup (g_strerror(errno));
-
+
error:
if (errstring)
g_warning ("error reading alias file: %s:%d: %s\n", filename, line, errstring);
g_free (errstring);
}
-
+
g_string_free (line_buffer, TRUE);
g_string_free (tmp_buffer1, TRUE);
g_string_free (tmp_buffer2, TRUE);
NULL);
read_alias_file (filename);
g_free (filename);
-
+
home = g_get_home_dir ();
if (home && *home)
{
{
struct PangoAlias alias_key;
struct PangoAlias *alias;
-
+
if (pango_aliases_ht == NULL)
pango_load_aliases ();
* @text: the text to process
* @length: length of @text in bytes (may be -1 if @text is nul-terminated)
*
- * Searches a string the first character that has a strong
+ * Searches a string the first character that has a strong
* direction, according to the Unicode bidirectional algorithm.
*
* Return value: The direction corresponding to the first strong character.
int thickness_pixels = (*thickness + PANGO_SCALE / 2) / PANGO_SCALE;
if (thickness_pixels == 0)
thickness_pixels = 1;
-
+
if (thickness_pixels & 1)
{
int new_center = ((*position - *thickness / 2) & ~(PANGO_SCALE - 1)) + PANGO_SCALE / 2;
* pango_extents_to_pixels:
* @ink_rect: ink rectangle to convert, or %NULL.
* @logical_rect: logical rectangle to convert, or %NULL.
- *
+ *
* Converts extents from Pango units to device units, dividing by the
* %PANGO_SCALE factor and performing rounding.
*
PangoATSUIFamily *atsuifamily = PANGO_ATSUI_FAMILY (family);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if (atsuifamily->n_faces < 0)
+ if (atsuifamily->n_faces < 0)
{
const char *real_family = get_real_family (atsuifamily->family_name);
NSArray *members = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:[NSString stringWithUTF8String:real_family]];
g_free (family->family_name);
- if (family->n_faces != -1)
+ if (family->n_faces != -1)
{
- for (i = 0; i < family->n_faces; i++)
+ for (i = 0; i < family->n_faces; i++)
{
g_object_unref (family->faces[i]);
}
-
+
g_free (family->faces);
}
{
GObjectClass *object_class = (GObjectClass *)class;
int i;
-
+
pango_atsui_family_parent_class = g_type_class_peek_parent (class);
object_class->finalize = pango_atsui_family_finalize;
0, /* n_preallocs */
(GInstanceInitFunc) pango_atsui_family_init,
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY,
I_("PangoATSUIFamily"),
&object_info, 0);
}
-
+
return object_type;
}
PangoStyle pango_style;
PangoVariant pango_variant;
int weight;
-
+
description = pango_font_description_new ();
pango_font_description_set_family (description, atsuiface->family->family_name);
pango_weight = PANGO_WEIGHT_ULTRABOLD;
else if (weight == 13 || weight == 14)
pango_weight = PANGO_WEIGHT_HEAVY;
- else
+ else
g_assert_not_reached ();
if (atsuiface->traits & NSItalicFontMask)
pango_font_description_set_weight (description, pango_weight);
pango_font_description_set_style (description, pango_style);
- return description;
+ return description;
}
static const char *
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FACE,
I_("PangoATSUIFace"),
&object_info, 0);
}
-
+
return object_type;
}
pango_atsui_font_map_finalize (GObject *object)
{
PangoATSUIFontMap *fontmap = PANGO_ATSUI_FONT_MAP (object);
-
+
g_hash_table_destroy (fontmap->font_hash);
g_hash_table_destroy (fontmap->families);
};
/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/)
- *
+ *
* Not necessarily better than a lot of other hashes, but should be OK, and
* well tested with binary data.
*/
hval *= FNV_32_PRIME;
hval ^= *buffer++;
}
-
+
return hval;
}
if (key->context_key)
PANGO_ATSUI_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
-
+
g_slice_free (FontHashKey, key);
}
font_hash_key_copy (FontHashKey *old)
{
FontHashKey *key = g_slice_new (FontHashKey);
-
+
key->fontmap = old->fontmap;
key->matrix = old->matrix;
key->desc = pango_font_description_copy (old->desc);
old->context_key);
else
key->context_key = NULL;
-
+
return key;
}
{
key->fontmap = fcfontmap;
get_context_matrix (context, &key->matrix);
-
+
if (PANGO_ATSUI_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
key->context_key = (gpointer)PANGO_ATSUI_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
else
const char *postscript_name)
{
FontHashKey key;
-
+
font_hash_key_for_context (atsuifontmap, context, &key);
key.postscript_name = (char *)postscript_name;
key.desc = desc;
PangoATSUIFace *best_face = NULL;
PangoATSUIFont *best_font;
int i;
-
+
/* Force a listing of the available faces */
pango_font_family_list_faces ((PangoFontFamily *)font_family, NULL, NULL);
for (i = 0; i < font_family->n_faces; i++)
{
new_desc = pango_font_face_describe (font_family->faces[i]);
-
+
if (pango_font_description_better_match (description, best_desc, new_desc))
{
pango_font_description_free (best_desc);
best_desc = new_desc;
best_face = (PangoATSUIFace *)font_family->faces[i];
}
- else
+ else
{
pango_font_description_free (new_desc);
}
}
-
+
if (best_desc == NULL || best_face == NULL)
return NULL;
pango_font_description_set_size (best_desc, size);
best_font = pango_atsui_font_map_lookup (atsuifontmap, context, best_desc, best_face->postscript_name);
-
+
if (best_font)
g_object_ref (best_font);
else
if (families)
{
int i = 0;
-
+
*families = g_new (PangoFontFamily *, *n_families);
tmp_list = family_list;
tmp_list = tmp_list->next;
}
}
-
+
g_slist_free (family_list);
}
-static void
+static void
pango_atsui_font_map_init (PangoATSUIFontMap *atsuifontmap)
{
NSArray *family_array;
atsuifontmap->families = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
-
+
atsuifontmap->font_hash = g_hash_table_new_full ((GHashFunc)font_hash_key_hash,
(GEqualFunc)font_hash_key_equal,
(GDestroyNotify)font_hash_key_free,
GObjectClass *object_class = G_OBJECT_CLASS (class);
PangoFontClass *font_class = PANGO_FONT_CLASS (class);
- object_class->finalize = pango_atsui_font_finalize;
+ object_class->finalize = pango_atsui_font_finalize;
font_class->describe = pango_atsui_font_describe;
font_class->get_coverage = pango_atsui_font_get_coverage;
if (!cafont->scaled_font)
g_error ("Unable to create ATSUI cairo scaled font.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
}
-
+
return cafont->scaled_font;
}
if (logical_rect)
cairo_scaled_font_extents (scaled_font, &font_extents);
-
+
cairo_glyph.index = glyph;
cairo_glyph.x = 0;
cairo_glyph.y = 0;
ink_rect->width = extents.width * PANGO_SCALE;
ink_rect->height = extents.height * PANGO_SCALE;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
metrics->approximate_char_width = ats_metrics.avgAdvanceWidth * cafont->size * PANGO_SCALE;
metrics->approximate_digit_width = ats_metrics.avgAdvanceWidth * cafont->size * PANGO_SCALE;
-
+
metrics->underline_position = ats_metrics.underlinePosition * cafont->size * PANGO_SCALE;
metrics->underline_thickness = ats_metrics.underlineThickness * cafont->size * PANGO_SCALE;
-
+
metrics->strikethrough_position = metrics->ascent / 3;
metrics->strikethrough_thickness = ats_metrics.underlineThickness * cafont->size * PANGO_SCALE;
const PangoMatrix *pango_ctm;
ATSUFontID font_id;
- cfstr = CFStringCreateWithCString (NULL, postscript_name,
+ cfstr = CFStringCreateWithCString (NULL, postscript_name,
kCFStringEncodingUTF8);
font_ref = ATSFontFindFromPostScriptName (cfstr, kATSOptionFlagsDefault);
font_id = FMGetFontFromATSFontRef (font_ref);
-
+
CFRelease (cfstr);
if (!font_id)
if (!pango_font_description_get_size_is_absolute (desc))
{
/* FIXME: Need to handle dpi here. See other font implementations for more info. */
- }
+ }
cairo_matrix_init_scale (&cafont->font_matrix, cafont->size, cafont->size);
pango_ctm = pango_context_get_matrix (context);
pango_cairo_atsui_font_map_get_renderer (PangoCairoFontMap *cfontmap)
{
PangoCairoATSUIFontMap *cwfontmap = PANGO_CAIRO_ATSUI_FONT_MAP (cfontmap);
-
+
if (!cwfontmap->renderer)
cwfontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
double dpi)
{
PangoCairoATSUIFontMap *cafontmap = PANGO_CAIRO_ATSUI_FONT_MAP (cfontmap);
-
+
cafontmap->dpi = dpi;
}
pango_cairo_atsui_font_map_finalize (GObject *object)
{
PangoCairoATSUIFontMap *cafontmap = PANGO_CAIRO_ATSUI_FONT_MAP (object);
-
+
if (cafontmap->renderer)
g_object_unref (cafontmap->renderer);
PangoGravity gravity;
PangoRectangle font_extents;
- GlyphExtentsCacheEntry *glyph_extents_cache;
+ GlyphExtentsCacheEntry *glyph_extents_cache;
};
struct _PangoCairoFcFontClass
if (!cffont->font_face)
{
cffont->font_face = cairo_ft_font_face_create_for_pattern (fcfont->font_pattern);
-
+
/* Unable to create FT2 cairo scaled font.
* This means out of memory or a cairo/fontconfig/FreeType bug,
*/
if (!cffont->font_face)
return NULL;
}
-
+
return cffont->font_face;
}
if (cffont->glyph_extents_cache)
{
g_free (cffont->glyph_extents_cache);
- }
+ }
G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object);
}
PangoFcFont *fcfont = (PangoFcFont *) (font);
PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font);
PangoFcMetricsInfo *info = NULL; /* Quiet gcc */
- GSList *tmp_list;
+ GSList *tmp_list;
const char *sample_str = pango_language_get_sample_string (language);
-
+
tmp_list = fcfont->metrics_by_lang;
while (tmp_list)
{
info = tmp_list->data;
-
+
if (info->sample_str == sample_str) /* We _don't_ need strcmp */
break;
return pango_font_metrics_new ();
info = g_slice_new0 (PangoFcMetricsInfo);
-
+
fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang, info);
-
+
info->sample_str = sample_str;
context = pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fcfont->fontmap));
cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont);
if (G_UNLIKELY (!scaled_font))
return NULL;
-
+
return cairo_ft_scaled_font_lock_face (scaled_font);
}
cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont);
if (G_UNLIKELY (!scaled_font))
return;
-
+
cairo_ft_scaled_font_unlock_face (scaled_font);
}
cairo_glyph.index = glyph;
cairo_glyph.x = 0;
cairo_glyph.y = 0;
-
+
cairo_scaled_font_glyph_extents (cffont->scaled_font,
&cairo_glyph, 1, &extents);
-
+
entry->glyph = glyph;
entry->width = pango_units_from_double (extents.x_advance);
entry->ink_rect.x = pango_units_from_double (extents.x_bearing);
entry->ink_rect.width = pango_units_from_double (extents.width);
entry->ink_rect.height = pango_units_from_double (extents.height);
}
-
+
static GlyphExtentsCacheEntry *
pango_cairo_fc_font_get_glyph_extents_cache_entry (PangoCairoFcFont *cffont,
PangoGlyph glyph)
*logical_rect = cffont->font_extents;
return;
}
- else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)
+ else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)
{
_pango_cairo_get_glyph_extents_missing((PangoCairoFont *)font, glyph, ink_rect, logical_rect);
return;
PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class);
object_class->finalize = pango_cairo_fc_font_finalize;
-
+
font_class->get_glyph_extents = pango_cairo_fc_font_get_glyph_extents;
font_class->get_metrics = pango_cairo_fc_font_get_metrics;
double size;
/* The reason why we read FC_PIXEL_SIZE here rather than just
- * using the specified size is to support operations like clamping
- * a font to a minimal readable size in fonts.conf. This is pretty weird,
- * since it could mean that changing the Cairo CTM doesn't change the
+ * using the specified size is to support operations like clamping
+ * a font to a minimal readable size in fonts.conf. This is pretty weird,
+ * since it could mean that changing the Cairo CTM doesn't change the
* font size, but it's just a more radical version of the non-linear
* font scaling we already have due to hinting and due to bitmap
* fonts being only available at a few sizes.
- *
+ *
* If honoring FC_PIXEL_SIZE gets in the way of more useful features
* it should be removed since it only matters in the unusual case
* of people doing exotic stuff in fonts.conf.
if (dpi <= 0)
dpi = cffontmap->dpi;
-
+
return dpi * pango_font_description_get_size (desc) / 72.;
}
}
const PangoMatrix *pango_ctm;
FcMatrix *fc_matrix;
double size;
-
+
g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (cffontmap), NULL);
g_return_val_if_fail (pattern != NULL, NULL);
cffont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
-
+
/* fcfont's is_hinted controls metric hinting
*/
- ((PangoFcFont *)(cffont))->is_hinted =
+ ((PangoFcFont *)(cffont))->is_hinted =
(cairo_font_options_get_hint_metrics(cffont->options) != CAIRO_HINT_METRICS_OFF);
return (PangoFcFont *) (cffont);
double dpi)
{
PangoCairoFcFontMap *cffontmap = (PangoCairoFcFontMap *) (cfontmap);
-
+
cffontmap->dpi = dpi;
pango_fc_font_map_cache_clear ((PangoFcFontMap *) (cfontmap));
pango_cairo_fc_font_map_get_renderer (PangoCairoFontMap *cfontmap)
{
PangoCairoFcFontMap *cffontmap = (PangoCairoFcFontMap *) (cfontmap);
-
+
if (!cffontmap->renderer)
cffontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
pango_cairo_fc_font_map_finalize (GObject *object)
{
PangoCairoFcFontMap *cffontmap = (PangoCairoFcFontMap *) (object);
-
+
if (cffontmap->renderer)
g_object_unref (cffontmap->renderer);
if (context)
cairo_ft_font_options_substitute (_pango_cairo_context_get_merged_font_options (context),
pattern);
-
+
FcDefaultSubstitute (pattern);
}
{
PangoCairoFcFontMap *cffontmap = (PangoCairoFcFontMap *) (fcfontmap);
double dpi;
-
+
if (context)
{
dpi = pango_cairo_context_get_resolution (context);
-
+
if (dpi <= 0)
dpi = cffontmap->dpi;
}
{
return cairo_font_options_equal (key_a, key_b);
}
-
+
static PangoFcFont *
pango_cairo_fc_font_map_create_font (PangoFcFontMap *fcfontmap,
PangoContext *context,
PangoFcFontMapClass *fcfontmap_class = PANGO_FC_FONT_MAP_CLASS (class);
gobject_class->finalize = pango_cairo_fc_font_map_finalize;
-
+
fcfontmap_class->context_substitute = pango_cairo_fc_font_map_context_substitute;
fcfontmap_class->get_resolution = pango_cairo_fc_font_map_get_resolution_fc;
-
+
fcfontmap_class->context_key_get = pango_cairo_fc_font_map_context_key_get;
fcfontmap_class->context_key_copy = pango_cairo_fc_font_map_context_key_copy;
fcfontmap_class->context_key_free = pango_cairo_fc_font_map_context_key_free;
fcfontmap_class->context_key_hash = pango_cairo_fc_font_map_context_key_hash;
fcfontmap_class->context_key_equal = pango_cairo_fc_font_map_context_key_equal;
-
+
fcfontmap_class->create_font = pango_cairo_fc_font_map_create_font;
}
}
return FALSE;
}
-
+
return (* PANGO_CAIRO_FONT_GET_IFACE (font)->install) (font, cr);
}
{
g_return_val_if_fail (PANGO_IS_CAIRO_FONT (font), NULL);
/* this function will be removed. don't bother with warning history here */
-
+
return (* PANGO_CAIRO_FONT_GET_IFACE (font)->get_font_face) (font);
}
}
return NULL;
}
-
+
return (* PANGO_CAIRO_FONT_GET_IFACE (font)->get_scaled_font) (font);
}
g_object_unref (hbi->font);
g_slice_free (PangoCairoHexBoxInfo, hbi);
}
-}
-
+}
+
PangoCairoHexBoxInfo *
_pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont)
{
if (hbi)
return hbi;
- scaled_font = _pango_cairo_font_get_scaled_font (cfont);
+ scaled_font = _pango_cairo_font_get_scaled_font (cfont);
if (!scaled_font)
{
- g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", NULL, NULL);
+ g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", NULL, NULL);
return NULL;
}
#define HINT(value, scale, scale_inv) (ceil ((value-1e-5) * scale) * scale_inv)
#define HINT_X(value) HINT ((value), scale_x, scale_x_inv)
#define HINT_Y(value) HINT ((value), scale_y, scale_y_inv)
-
+
/* create mini_font description */
{
PangoContext *context;
mini_cfont = (PangoCairoFont *) mini_font;
- scaled_mini_font = _pango_cairo_font_get_scaled_font (mini_cfont);
+ scaled_mini_font = _pango_cairo_font_get_scaled_font (mini_cfont);
for (i = 0 ; i < 16 ; i++)
{
hbi->box_descent = HINT_Y (hbi->box_descent);
}
- g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", hbi, (GDestroyNotify)_pango_cairo_hex_box_info_destroy);
+ g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", hbi, (GDestroyNotify)_pango_cairo_hex_box_info_destroy);
return hbi;
}
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
{
- PangoCairoHexBoxInfo *hbi;
+ PangoCairoHexBoxInfo *hbi;
gint rows, cols;
hbi = _pango_cairo_font_get_hex_box_info (cfont);
rows = hbi->rows;
cols = ((glyph & ~PANGO_GLYPH_UNKNOWN_FLAG) > 0xffff ? 6 : 4) / rows;
-
+
if (ink_rect)
{
ink_rect->x = PANGO_SCALE * hbi->pad_x;
ink_rect->width = PANGO_SCALE * (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
ink_rect->height = PANGO_SCALE * hbi->box_height;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
logical_rect->y = PANGO_SCALE * (hbi->box_descent - (hbi->box_height + hbi->pad_y));
logical_rect->width = PANGO_SCALE * (5 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
logical_rect->height = PANGO_SCALE * (hbi->box_height + 2 * hbi->pad_y);
- }
+ }
}
/**
* pango_cairo_font_map_new:
- *
+ *
* Creates a new #PangoCairoFontMap object; a fontmap is used
* to cache information about available fonts, and holds
* certain global parameters such as the resolution.
* on the particular font backend Cairo was compiled to use;
* You generally should only use the #PangoFontMap and
* #PangoCairoFontMap interfaces on the returned object.
- *
+ *
* Return value: the newly allocated #PangoFontMap, which should
* be freed with g_object_unref().
*
/**
* pango_cairo_font_map_get_default:
- *
- * Gets a default font map to use with Cairo.
- *
+ *
+ * Gets a default font map to use with Cairo.
+ *
* Return value: the default Cairo fontmap for #Pango. This
* object is owned by Pango and must not be freed.
*
/**
* pango_cairo_font_map_set_resolution:
- * @fontmap: a #PangoCairoFontMap
+ * @fontmap: a #PangoCairoFontMap
* @dpi: the resolution in "dots per inch". (Physical inches aren't actually
* involved; the terminology is conventional.)
- *
+ *
* Sets the resolution for the fontmap. This is a scale factor between
* points specified in a #PangoFontDescription and Cairo units. The
* default value is 96, meaning that a 10 point font will be 13
double dpi)
{
g_return_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap));
-
+
(* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->set_resolution) (fontmap, dpi);
}
/**
* pango_cairo_font_map_get_resolution:
- * @fontmap: a #PangoCairoFontMap
- *
+ * @fontmap: a #PangoCairoFontMap
+ *
* Gets the resolution for the fontmap. See pango_cairo_font_map_set_resolution()
*
* Return value: the resolution in "dots per inch"
pango_cairo_font_map_get_resolution (PangoCairoFontMap *fontmap)
{
g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), 96.);
-
+
return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_resolution) (fontmap);
}
/**
* pango_cairo_font_map_create_context:
* @fontmap: a #PangoCairoFontMap
- *
+ *
* Create a #PangoContext for the given fontmap.
- *
+ *
* Return value: the newly created context; free with g_object_unref().
*
* Since: 1.10
pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap)
{
PangoContext *context;
-
+
g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL);
-
+
context = pango_context_new ();
pango_context_set_font_map (context, PANGO_FONT_MAP (fontmap));
/**
* _pango_cairo_font_map_get_renderer:
* @fontmap: a #PangoCairoFontmap
- *
+ *
* Gets the singleton #PangoCairoRenderer for this fontmap.
- *
+ *
* Return value: the singleton renderer
**/
PangoRenderer *
_pango_cairo_font_map_get_renderer (PangoCairoFontMap *fontmap)
{
g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL);
-
+
return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_renderer) (fontmap);
}
struct _PangoCairoContextInfo
{
double dpi;
-
+
cairo_font_options_t *set_options;
cairo_font_options_t *surface_options;
cairo_font_options_t *merged_options;
cairo_font_options_destroy (info->surface_options);
if (info->merged_options)
cairo_font_options_destroy (info->merged_options);
-
+
g_slice_free (PangoCairoContextInfo, info);
}
info->surface_options = NULL;
info->merged_options = NULL;
- g_object_set_qdata_full (G_OBJECT (context), context_info_quark,
+ g_object_set_qdata_full (G_OBJECT (context), context_info_quark,
info, (GDestroyNotify)free_context_info);
}
* pango_cairo_update_context:
* @cr: a Cairo context
* @context: a #PangoContext, from pango_cairo_font_map_create_context()
- *
+ *
* Updates a #PangoContext previously created for use with Cairo to
* match the current transformation and target surface of a Cairo
* context. If any layouts have been created for the context,
cairo_matrix_t cairo_matrix;
cairo_surface_t *target;
PangoMatrix pango_matrix;
-
+
g_return_if_fail (cr != NULL);
g_return_if_fail (PANGO_IS_CONTEXT (context));
target = cairo_get_target (cr);
cairo_surface_get_font_options (target, info->surface_options);
-
+
if (info->merged_options)
{
cairo_font_options_destroy (info->merged_options);
* @dpi: the resolution in "dots per inch". (Physical inches aren't actually
* involved; the terminology is conventional.) A 0 or negative value
* means to use the resolution from the font map.
- *
+ *
* Sets the resolution for the context. This is a scale factor between
* points specified in a #PangoFontDescription and Cairo units. The
* default value is 96, meaning that a 10 point font will be 13
/**
* pango_cairo_context_get_resolution:
* @context: a #PangoContext, from pango_cairo_font_map_create_context()
- *
+ *
* Gets the resolution for the context. See pango_cairo_context_set_resolution()
*
* Return value: the resolution in "dots per inch". A negative value will
* @context: a #PangoContext, from pango_cairo_font_map_create_context()
* @options: a #cairo_font_options_t, or %NULL to unset any previously set
* options. A copy is made.
- *
+ *
* Sets the font options used when rendering text with this context.
* These options override any options that pango_cairo_update_context()
* derives from the target surface.
*/
-void
+void
pango_cairo_context_set_font_options (PangoContext *context,
const cairo_font_options_t *options)
{
PangoCairoContextInfo *info;
g_return_if_fail (PANGO_IS_CONTEXT (context));
-
+
info = get_context_info (context, TRUE);
if (info->set_options)
info->set_options = cairo_font_options_copy (options);
else
info->set_options = NULL;
-
+
if (info->merged_options)
{
cairo_font_options_destroy (info->merged_options);
info->merged_options = NULL;
}
}
-
+
/**
* pango_cairo_context_get_font_options:
* @context: a #PangoContext, from pango_cairo_font_map_create_context()
- *
+ *
* Retrieves any font rendering options previously set with
* pango_cairo_font_map_set_font_options(). This functions not report options
* that are derived from the target surface by pango_cairo_update_context()
- *
+ *
* Return value: the font options previously set on the context, or %NULL
* if no options have been set. This value is owned by the context
* and must not be modified or freed.
pango_cairo_context_get_font_options (PangoContext *context)
{
PangoCairoContextInfo *info;
-
+
g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
info = get_context_info (context, FALSE);
* _pango_cairo_context_merge_font_options:
* @context: a #PangoContext
* @options: a #cairo_font_options_t
- *
+ *
* Merge together options from the target surface and explicitly set
* on the context.
*
/**
* pango_cairo_create_layout:
* @cr: a Cairo context
- *
+ *
* Creates a layout object set up to match the current transformation
* and target surface of the Cairo context. This layout can then be
* used for text measurement with functions like
* however it is slightly inefficient since it creates a separate
* #PangoContext object for each layout. This might matter in an
* application that was laying out large amounts of text.
- *
+ *
* Return value: the newly created #PangoLayout. Free with
* g_object_unref().
*
* pango_cairo_update_layout:
* @cr: a Cairo context
* @layout: a #PangoLayout, from pango_cairo_create_layout()
- *
+ *
* Updates the private #PangoContext of a #PangoLayout created with
* pango_cairo_create_layout() to match the current transformation
* and target surface of a Cairo context.
struct _PangoCairoWarningHistory {
guint font_install : 1;
guint font_get_scaled_font : 1;
-};
+};
extern PangoCairoWarningHistory _pango_cairo_warning_history;
PangoRenderPart part)
{
PangoColor *color = pango_renderer_get_color ((PangoRenderer *) (crenderer), part);
-
+
if (color)
cairo_set_source_rgb (crenderer->cr,
color->red / 65535.,
cairo_save (crenderer->cr);
cairo_get_current_point (crenderer->cr, &temp_x, &temp_y);
- hbi = _pango_cairo_font_get_hex_box_info ((PangoCairoFont *)font);
+ hbi = _pango_cairo_font_get_hex_box_info ((PangoCairoFont *)font);
if (!hbi || !_pango_cairo_font_install ((PangoCairoFont *) (hbi->font), crenderer->cr))
{
cairo_move_to (crenderer->cr, temp_x, temp_y);
cairo_restore (crenderer->cr);
}
-
+
static void
pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer,
PangoFont *font,
/* cairo_glyph_t is 24 bytes */
#define MAX_STACK 40
-
+
int i, count;
int x_position = 0;
cairo_glyph_t *cairo_glyphs;
base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
_pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
- }
+ }
x_position += gi->geometry.width;
}
cairo_glyphs[count].y = cy;
count++;
}
- }
+ }
x_position += gi->geometry.width;
}
cairo_glyph_path (crenderer->cr, cairo_glyphs, count);
else
cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
-
+
if (glyphs->num_glyphs > MAX_STACK)
g_free (cairo_glyphs);
done:
cairo_restore (crenderer->cr);
-
+
#undef MAX_STACK
}
cairo_rectangle (crenderer->cr,
crenderer->x_offset + (double)x / PANGO_SCALE,
- crenderer->y_offset + (double)y / PANGO_SCALE,
+ crenderer->y_offset + (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
if (!crenderer->do_path)
{
cairo_fill (crenderer->cr);
-
+
cairo_restore (crenderer->cr);
}
}
* A/ \ / \ / \ A/ \ / \ |
* \ \ / \ / /D \ \ / \ |
* \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square
- * \ /\ F / \ F /\ \ |
+ * \ /\ F / \ F /\ \ |
* \ / \ / \ / \ \G |
* \ / \ / \ / \ / |
* \/ \/ \/ \/ -
- * B B
+ * B B
* |---|
* unit_width = (HEIGHT_SQUARES - 1) * square
*
y_top = y;
y_bottom = y + height;
-
+
/* Bottom of squiggle */
cairo_move_to (cr, x - square / 2, y_top + square / 2); /* A */
for (i = 0; i < width_units; i += 2)
{
double x_middle = x + (i + 1) * unit_width;
double x_right = x + (i + 2) * unit_width;
-
+
cairo_line_to (cr, x_middle, y_bottom); /* B */
-
+
if (i + 1 == width_units)
/* Nothing */;
else if (i + 2 == width_units)
else
cairo_line_to (cr, x_right, y_top + square); /* C */
}
-
+
/* Top of squiggle */
for (i -= 2; i >= 0; i -= 2)
{
double x_left = x + i * unit_width;
double x_middle = x + (i + 1) * unit_width;
double x_right = x + (i + 2) * unit_width;
-
+
if (i + 1 == width_units)
cairo_line_to (cr, x_middle + square / 2, y_bottom - square / 2); /* G */
else {
cairo_line_to (cr, x_right, y_top); /* E */
cairo_line_to (cr, x_middle, y_bottom - square); /* F */
}
-
+
cairo_line_to (cr, x_left, y_top); /* H */
}
}
cairo_save (cr);
set_color (crenderer, PANGO_RENDER_PART_UNDERLINE);
-
+
cairo_new_path (cr);
}
crenderer->x_offset + (double)x / PANGO_SCALE,
crenderer->y_offset + (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
-
+
if (!crenderer->do_path)
{
cairo_fill (cr);
* prepare_run() isn't called.
*/
- pango_renderer_activate (renderer);
-
- pango_renderer_set_color (renderer, PANGO_RENDER_PART_FOREGROUND, NULL);
- pango_renderer_set_color (renderer, PANGO_RENDER_PART_BACKGROUND, NULL);
- pango_renderer_set_color (renderer, PANGO_RENDER_PART_UNDERLINE, NULL);
- pango_renderer_set_color (renderer, PANGO_RENDER_PART_STRIKETHROUGH, NULL);
+ pango_renderer_activate (renderer);
+
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_FOREGROUND, NULL);
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_BACKGROUND, NULL);
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_UNDERLINE, NULL);
+ pango_renderer_set_color (renderer, PANGO_RENDER_PART_STRIKETHROUGH, NULL);
}
-
+
pango_renderer_draw_glyphs (renderer, font, glyphs, 0, 0);
if (!do_path)
{
pango_renderer_deactivate (renderer);
}
-
+
release_renderer (crenderer, free_renderer);
}
cairo_get_current_point (cr, &crenderer->x_offset, &crenderer->y_offset);
pango_renderer_draw_layout_line (renderer, line, 0, 0);
-
+
release_renderer (crenderer, free_renderer);
}
gboolean free_renderer;
PangoCairoRenderer *crenderer = acquire_renderer (&free_renderer);
PangoRenderer *renderer = (PangoRenderer *) crenderer;
-
+
crenderer->cr = cr;
crenderer->do_path = do_path;
cairo_get_current_point (cr, &crenderer->x_offset, &crenderer->y_offset);
pango_renderer_draw_layout (renderer, layout, 0, 0);
-
+
release_renderer (crenderer, free_renderer);
}
-static void
-_pango_cairo_do_error_underline (cairo_t *cr,
+static void
+_pango_cairo_do_error_underline (cairo_t *cr,
double x,
double y,
double width,
double height,
gboolean do_path)
-{
+{
/* We don't use a renderer here, for a simple reason:
* the only renderer we can get is the default renderer, that
* is all implemented here, so we shortcircuit and make our
if (!do_path)
cairo_fill (cr);
-}
+}
/* public wrapper of above to show or append path */
* @cr: a Cairo context
* @font: a #PangoFont
* @glyphs: a #PangoGlyphString
- *
+ *
* Draws the glyphs in @glyphs in the specified cairo context.
* The origin of the glyphs (the left edge of the baseline) will
* be drawn at the current point of the cairo context.
* pango_cairo_show_layout_line:
* @cr: a Cairo context
* @line: a #PangoLayoutLine
- *
+ *
* Draws a #PangoLayoutLine in the specified cairo context.
* The origin of the glyphs (the left edge of the line) will
* be drawn at the current point of the cairo context.
* pango_cairo_show_layout:
* @cr: a Cairo context
* @layout: a Pango layout
- *
+ *
* Draws a #PangoLayoutLine in the specified cairo context.
* The top-left corner of the #PangoLayout will be drawn
* at the current point of the cairo context.
* @y: The Y coordinate of one corner of the rectangle
* @width: Non-negative width of the rectangle
* @height: Non-negative height of the rectangle
- *
+ *
* Draw a squiggly line in the specified cairo context that approximately
* covers the given rectangle in the style of an underline used to indicate a
* spelling error. (The width of the underline is rounded to an integer
*
* Since: 1.14
**/
-void
-pango_cairo_show_error_underline (cairo_t *cr,
+void
+pango_cairo_show_error_underline (cairo_t *cr,
double x,
double y,
double width,
double height)
-{
+{
g_return_if_fail (cr != NULL);
- g_return_if_fail ((width >= 0) && (height >= 0));
-
- _pango_cairo_do_error_underline (cr, x, y, width, height, FALSE);
-}
+ g_return_if_fail ((width >= 0) && (height >= 0));
+
+ _pango_cairo_do_error_underline (cr, x, y, width, height, FALSE);
+}
/**
* pango_cairo_glyph_string_path
* @cr: a Cairo context
* @font: a #PangoFont
* @glyphs: a #PangoGlyphString
- *
+ *
* Adds the glyphs in @glyphs to the current path in the specified
* cairo context. The origin of the glyphs (the left edge of the baseline)
* will be at the current point of the cairo context.
* pango_cairo_layout_line_path:
* @cr: a Cairo context
* @line: a #PangoLayoutLine
- *
+ *
* Adds the text in #PangoLayoutLine to the current path in the
* specified cairo context. The origin of the glyphs (the left edge
* of the line) will be at the current point of the cairo context.
* pango_cairo_layout_path:
* @cr: a Cairo context
* @layout: a Pango layout
- *
+ *
* Adds the text in a #PangoLayout to the current path in the
* specified cairo context. The top-left corner of the #PangoLayout
* will be at the current point of the cairo context.
* @y: The Y coordinate of one corner of the rectangle
* @width: Non-negative width of the rectangle
* @height: Non-negative height of the rectangle
- *
+ *
* Add a squiggly line to the current path in the specified cairo context that
* approximately covers the given rectangle in the style of an underline used
* to indicate a spelling error. (The width of the underline is rounded to an
*
* Since: 1.14
**/
-void
-pango_cairo_error_underline_path (cairo_t *cr,
+void
+pango_cairo_error_underline_path (cairo_t *cr,
double x,
double y,
double width,
{
g_return_if_fail (cr != NULL);
g_return_if_fail ((width >= 0) && (height >= 0));
-
- _pango_cairo_do_error_underline (cr, x, y, width, height, TRUE);
+
+ _pango_cairo_do_error_underline (cr, x, y, width, height, TRUE);
}
cairo_font_face_t *font_face;
cairo_scaled_font_t *scaled_font;
-
+
cairo_matrix_t font_matrix;
cairo_matrix_t ctm;
cairo_font_options_t *options;
-
+
GSList *metrics_by_lang;
GHashTable *glyph_info;
};
* last field
*/
memcpy (&logfontw, &win32font->logfont, sizeof (LOGFONTA));
-
+
if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
win32font->logfont.lfFaceName, -1,
logfontw.lfFaceName, G_N_ELEMENTS (logfontw.lfFaceName)))
logfontw.lfFaceName[0] = 0; /* Hopefully this will select some font */
-
+
cwfont->font_face = cairo_win32_font_face_create_for_logfontw (&logfontw);
/* Failure of the above should only occur for out of memory,
if (!cwfont->font_face)
g_error ("Unable to create Win32 cairo font face.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
}
-
+
return cwfont->font_face;
}
if (!cwfont->scaled_font)
g_error ("Unable to create Win32 cairo scaled font.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
}
-
+
return cwfont->scaled_font;
}
g_hash_table_destroy (cwfont->glyph_info);
g_slist_foreach (cwfont->metrics_by_lang, (GFunc)free_metrics_info, NULL);
- g_slist_free (cwfont->metrics_by_lang);
+ g_slist_free (cwfont->metrics_by_lang);
if (cwfont->scaled_font)
cairo_scaled_font_destroy (cwfont->scaled_font);
cairo_font_extents_t font_extents;
cairo_text_extents_t extents;
cairo_glyph_t cairo_glyph;
-
+
cairo_scaled_font_extents (scaled_font, &font_extents);
-
+
logical_rect->x = 0;
logical_rect->y = - font_extents.ascent * PANGO_SCALE;
logical_rect->width = 0;
cairo_glyph.index = glyph;
cairo_glyph.x = 0;
cairo_glyph.y = 0;
-
+
cairo_scaled_font_glyph_extents (scaled_font,
&cairo_glyph, 1, &extents);
-
+
ink_rect->x = extents.x_bearing * PANGO_SCALE;
ink_rect->y = extents.y_bearing * PANGO_SCALE;
ink_rect->width = extents.width * PANGO_SCALE;
ink_rect->height = extents.height * PANGO_SCALE;
-
+
logical_rect->width = extents.x_advance * PANGO_SCALE;
}
}
if (!info)
{
info = g_new0 (PangoCairoWin32GlyphInfo, 1);
-
+
compute_glyph_extents (font, glyph,
&info->ink_rect,
&info->logical_rect);
-
+
g_hash_table_insert (cwfont->glyph_info, GUINT_TO_POINTER (glyph), info);
}
return info;
}
-
+
static void
pango_cairo_win32_font_get_glyph_extents (PangoFont *font,
PangoGlyph glyph,
PangoCairoWin32GlyphInfo *info;
info = pango_cairo_win32_font_get_glyph_info (font, glyph);
-
+
if (ink_rect)
*ink_rect = info->ink_rect;
if (logical_rect)
cairo_scaled_font_t *scaled_font;
cairo_font_extents_t font_extents;
double height;
-
+
metrics = pango_font_metrics_new ();
-
+
scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (cwfont));
cairo_scaled_font_extents (scaled_font, &font_extents);
cairo_win32_scaled_font_done_font (scaled_font);
-
+
metrics->ascent = font_extents.ascent * PANGO_SCALE;
metrics->descent = font_extents.descent * PANGO_SCALE;
layout = pango_layout_new (context);
font_desc = pango_font_describe_with_absolute_size (font);
pango_layout_set_font_description (layout, font_desc);
- pango_layout_set_text (layout, sample_str, -1);
+ pango_layout_set_text (layout, sample_str, -1);
pango_layout_get_extents (layout, NULL, &extents);
-
+
metrics->approximate_char_width = extents.width / g_utf8_strlen (sample_str, -1);
pango_layout_set_text (layout, "0123456789", -1);
PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
PangoWin32MetricsInfo *info = NULL; /* Quiet gcc */
- GSList *tmp_list;
+ GSList *tmp_list;
const char *sample_str = pango_language_get_sample_string (language);
-
+
tmp_list = cwfont->metrics_by_lang;
while (tmp_list)
{
info = tmp_list->data;
-
+
if (info->sample_str == sample_str) /* We _don't_ need strcmp */
break;
return pango_font_metrics_new ();
info = g_slice_new0 (PangoWin32MetricsInfo);
-
- cwfont->metrics_by_lang = g_slist_prepend (cwfont->metrics_by_lang,
+
+ cwfont->metrics_by_lang = g_slist_prepend (cwfont->metrics_by_lang,
info);
-
+
info->sample_str = sample_str;
context = pango_context_new ();
HDC hdc)
{
cairo_scaled_font_t *scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (font));
-
+
return cairo_win32_scaled_font_select_font (scaled_font, hdc) == CAIRO_STATUS_SUCCESS;
}
pango_cairo_win32_font_done_font (PangoFont *font)
{
cairo_scaled_font_t *scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (font));
-
+
cairo_win32_scaled_font_done_font (scaled_font);
}
PangoWin32FontClass *win32_font_class = PANGO_WIN32_FONT_CLASS (class);
object_class->finalize = pango_cairo_win32_font_finalize;
-
+
font_class->get_glyph_extents = pango_cairo_win32_font_get_glyph_extents;
font_class->get_metrics = pango_cairo_win32_font_get_metrics;
if (context)
{
dpi = pango_cairo_context_get_resolution (context);
-
+
if (dpi <= 0)
dpi = cwfontmap->dpi;
}
else
dpi = cwfontmap->dpi;
-
+
if (!pango_font_description_get_size_is_absolute (desc))
size *= dpi / 72.;
#ifdef USE_FACE_CACHED_FONTS
win32fontmap = PANGO_WIN32_FONT_MAP (cwfontmap);
-
+
tmp_list = face->cached_fonts;
while (tmp_list)
{
g_object_ref (win32font);
if (win32font->in_cache)
pango_win32_fontmap_cache_remove (PANGO_FONT_MAP (win32fontmap), win32font);
-
+
return PANGO_FONT (win32font);
}
tmp_list = tmp_list->next;
#endif
cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL);
win32font = PANGO_WIN32_FONT (cwfont);
-
+
win32font->fontmap = PANGO_FONT_MAP (cwfontmap);
g_object_ref (cwfontmap);
&win32font->logfont);
cwfont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
-
+
return PANGO_FONT (cwfont);
}
double dpi)
{
PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (cfontmap);
-
+
cwfontmap->dpi = dpi;
}
pango_cairo_win32_font_map_get_renderer (PangoCairoFontMap *cfontmap)
{
PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (cfontmap);
-
+
if (!cwfontmap->renderer)
cwfontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
pango_cairo_win32_font_map_finalize (GObject *object)
{
PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (object);
-
+
if (cwfontmap->renderer)
g_object_unref (cwfontmap->renderer);
/**
* PangoCairoFontMap:
- *
+ *
* #PangoCairoFontMap is an interface exported by font maps for
* use with Cairo. The actual type of the font map will depend
* on the particular font technology Cairo was compiled to use.
void pango_cairo_show_layout (cairo_t *cr,
PangoLayout *layout);
-void pango_cairo_show_error_underline (cairo_t *cr,
+void pango_cairo_show_error_underline (cairo_t *cr,
double x,
double y,
double width,
PangoLayoutLine *line);
void pango_cairo_layout_path (cairo_t *cr,
PangoLayout *layout);
-
-void pango_cairo_error_underline_path (cairo_t *cr,
+
+void pango_cairo_error_underline_path (cairo_t *cr,
double x,
double y,
double width,
* pangofc-decoder.h: Custom encoders/decoders on a per-font basis.
*
* Copyright (C) 2004 Red Hat Software
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
guint32 wc);
/*< private >*/
-
+
/* Padding for future expansion */
void (*_pango_reserved1) (void);
void (*_pango_reserved2) (void);
{
PangoFcDecoder *decoder;
gpointer context_key;
- GUnicharToGlyphCacheEntry *char_to_glyph_cache;
+ GUnicharToGlyphCacheEntry *char_to_glyph_cache;
};
#define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */
class->has_char = pango_fc_font_real_has_char;
class->get_glyph = pango_fc_font_real_get_glyph;
class->get_unknown_glyph = NULL;
-
+
object_class->finalize = pango_fc_font_finalize;
object_class->set_property = pango_fc_font_set_property;
font_class->describe = pango_fc_font_describe;
font_class->get_coverage = pango_fc_font_get_coverage;
font_class->get_metrics = pango_fc_font_get_metrics;
font_class->get_font_map = pango_fc_font_get_font_map;
-
+
g_object_class_install_property (object_class, PROP_PATTERN,
g_param_spec_pointer ("pattern",
"Pattern",
PangoFcFontPrivate *priv = fcfont->priv;
g_slist_foreach (fcfont->metrics_by_lang, (GFunc)free_metrics_info, NULL);
- g_slist_free (fcfont->metrics_by_lang);
+ g_slist_free (fcfont->metrics_by_lang);
if (fcfont->fontmap)
_pango_fc_font_map_remove (PANGO_FC_FONT_MAP (fcfont->fontmap), fcfont);
if (FcPatternGetBool (pattern,
FC_HINTING, 0, &hinting) != FcResultMatch)
hinting = FcTrue;
-
+
return hinting;
}
if (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
{
FT_Matrix ft_matrix;
-
+
ft_matrix.xx = 0x10000L * fc_matrix->xx;
ft_matrix.yy = 0x10000L * fc_matrix->yy;
ft_matrix.xy = 0x10000L * fc_matrix->xy;
{
PangoFcFont *fcfont = PANGO_FC_FONT (object);
FcPattern *pattern = g_value_get_pointer (value);
-
+
g_return_if_fail (pattern != NULL);
g_return_if_fail (fcfont->font_pattern == NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ break;
}
}
{
static guint engine_type_id = 0;
static guint render_type_id = 0;
-
+
if (engine_type_id == 0)
{
engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_FC);
}
-
+
return pango_find_map (language, engine_type_id, render_type_id);
}
ft_matrix.yy = 0x10000L * fc_matrix->yy;
ft_matrix.xy = 0x10000L * fc_matrix->xy;
ft_matrix.yx = 0x10000L * fc_matrix->yx;
-
+
have_transform = (ft_matrix.xx != 0x10000 || ft_matrix.xy != 0 ||
ft_matrix.yx != 0 || ft_matrix.yy != 0x10000);
}
if (have_transform)
{
FT_Vector vector;
-
+
vector.x = 0;
vector.y = face->size->metrics.descender;
FT_Vector_Transform (&vector, &ft_matrix);
metrics->descent = - PANGO_UNITS_26_6 (vector.y);
-
+
vector.x = 0;
vector.y = face->size->metrics.ascender;
FT_Vector_Transform (&vector, &ft_matrix);
else
{
FT_Fixed ft_thickness, ft_position;
-
+
ft_thickness = FT_MulFix (face->underline_thickness, face->size->metrics.y_scale);
metrics->underline_thickness = PANGO_UNITS_26_6 (ft_thickness);
if (os2 && os2->version != 0xFFFF && os2->yStrikeoutSize != 0)
{
FT_Fixed ft_thickness, ft_position;
-
+
ft_thickness = FT_MulFix (os2->yStrikeoutSize, face->size->metrics.y_scale);
metrics->strikethrough_thickness = PANGO_UNITS_26_6 (ft_thickness);
pango_quantize_line_geometry (&metrics->strikethrough_thickness,
&metrics->strikethrough_position);
}
-
+
PANGO_FC_FONT_UNLOCK_FACE (fcfont);
}
PangoLanguage *language = pango_context_get_language (context);
const char *sample_str = pango_language_get_sample_string (language);
PangoFontDescription *desc = pango_font_describe_with_absolute_size (fcfont);
-
+
metrics = pango_font_metrics_new ();
-
+
get_face_metrics (fcfont, metrics);
-
+
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
-
- pango_layout_set_text (layout, sample_str, -1);
+
+ pango_layout_set_text (layout, sample_str, -1);
pango_layout_get_extents (layout, NULL, &extents);
-
- metrics->approximate_char_width =
+
+ metrics->approximate_char_width =
extents.width / g_utf8_strlen (sample_str, -1);
pango_layout_set_text (layout, "0123456789", -1);
{
PangoFcFont *fcfont = PANGO_FC_FONT (font);
PangoFcMetricsInfo *info = NULL; /* Quiet gcc */
- GSList *tmp_list;
+ GSList *tmp_list;
const char *sample_str = pango_language_get_sample_string (language);
-
+
tmp_list = fcfont->metrics_by_lang;
while (tmp_list)
{
info = tmp_list->data;
-
+
if (info->sample_str == sample_str) /* We _don't_ need strcmp */
break;
info = g_slice_new0 (PangoFcMetricsInfo);
- fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang,
+ fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang,
info);
-
+
info->sample_str = sample_str;
context = pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fcfont->fontmap));
entry->ch = wc;
entry->glyph = index;
-
+
PANGO_FC_FONT_UNLOCK_FACE (font);
}
pango_fc_font_unlock_face (PangoFcFont *font)
{
g_return_if_fail (PANGO_IS_FC_FONT (font));
-
+
PANGO_FC_FONT_UNLOCK_FACE (font);
}
* pango_fc_font_has_char:
* @font: a #PangoFcFont
* @wc: Unicode codepoint to look up
- *
+ *
* Determines whether @font has a glyph for the codepoint @wc.
- *
+ *
* Return value: %TRUE if @font has the requested codepoint.
*
* Since: 1.4
* pango_fc_font_get_glyph:
* @font: a #PangoFcFont
* @wc: Unicode character to look up
- *
+ *
* Gets the glyph index for a given Unicode character
* for @font. If you only want to determine
* whether the font has the glyph, use pango_fc_font_has_char().
- *
+ *
* Return value: the glyph index, or 0, if the Unicode
* character doesn't exist in the font.
*
* pango_fc_font_kern_glyphs
* @font: a #PangoFcFont
* @glyphs: a #PangoGlyphString
- *
+ *
* Adjust each adjacent pair of glyphs in @glyphs according to
* kerning information in @font.
- *
+ *
* Since: 1.4
**/
void
PANGO_FC_FONT_UNLOCK_FACE (font);
return;
}
-
+
for (i = 1; i < glyphs->num_glyphs; ++i)
{
error = FT_Get_Kerning (face,
if (error == FT_Err_Ok)
glyphs->glyphs[i-1].geometry.width += PANGO_UNITS_26_6 (kerning.x);
}
-
+
PANGO_FC_FONT_UNLOCK_FACE (font);
}
{
FT_Error error;
FT_Glyph_Metrics *result;
-
+
error = FT_Load_Glyph (face, glyph, load_flags);
if (error == FT_Err_Ok)
result = &face->glyph->metrics;
* @glyph: the glyph index to load
* @ink_rect: location to store ink extents of the glyph, or %NULL
* @logical_rect: location to store logical extents of the glyph or %NULL
- *
+ *
* Gets the extents of a single glyph from a font. The extents are in
* user space; that is, they are not transformed by any matrix in effect
* for the font.
gm = NULL;
else
gm = get_per_char (face, load_flags, glyph);
-
+
if (gm)
{
if (ink_rect)
else
{
FT_Fixed ascender, descender;
-
+
ascender = FT_MulFix (face->ascender, face->size->metrics.y_scale);
descender = FT_MulFix (face->descender, face->size->metrics.y_scale);
-
+
logical_rect->y = - PANGO_UNITS_26_6 (ascender);
logical_rect->height = PANGO_UNITS_26_6 (ascender - descender);
}
logical_rect->height = 0;
}
}
-
+
PANGO_FC_FONT_UNLOCK_FACE (fcfont);
}
/**
* PANGO_RENDER_TYPE_FC:
- *
+ *
* A string constant used to identify shape engines that work
* with the fontconfig based backends. See the @engine_type field
* of #PangoEngineInfo.
/**
* PangoFcFont:
- *
+ *
* #PangoFcFont is a base class for font implementations
* using the Fontconfig and FreeType libraries and is used in
* conjunction with #PangoFcFontMap. When deriving from this
gpointer priv; /* used internally */
PangoMatrix matrix; /* used internally */
PangoFontDescription *description;
-
+
GSList *metrics_by_lang;
guint is_hinted : 1;
struct _PangoFcFontMapPrivate
{
GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoFcPatternSet */
-
+
/* pattern_hash is used to make sure we only store one copy of
* each identical pattern. (Speeds up lookup).
*/
- GHashTable *pattern_hash;
+ GHashTable *pattern_hash;
GHashTable *coverage_hash; /* Maps font file name/id -> PangoCoverage */
GHashTable *font_hash; /* Maps FcPattern -> PangoFcFont */
struct _PangoFcCoverageKey
{
- char *filename;
+ char *filename;
int id; /* needed to handle TTC files with multiple faces */
};
FcPattern **patterns;
PangoFontset *fontset;
GList *cache_link;
-
+
FontsetHashKey *key;
};
G_DEFINE_TYPE (PangoFcFontMap, pango_fc_font_map, PANGO_TYPE_FONT_MAP)
-static void
+static void
pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
{
static gboolean registered_modules = FALSE;
if (!registered_modules)
{
int i;
-
+
registered_modules = TRUE;
-
+
for (i = 0; _pango_included_fc_modules[i].list; i++)
pango_module_register (&_pango_included_fc_modules[i]);
}
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
-
+
object_class->finalize = pango_fc_font_map_finalize;
fontmap_class->load_font = pango_fc_font_map_load_font;
fontmap_class->load_fontset = pango_fc_font_map_load_fontset;
hash ^= (guint) (d*1000.0);
return hash;
-#endif
+#endif
}
static gboolean
};
/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/)
- *
+ *
* Not necessarily better than a lot of other hashes, but should be OK, and
* well tested with binary data.
*/
hval *= FNV_32_PRIME;
hval ^= *buffer++;
}
-
+
return hval;
}
if (key->context_key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
-
+
g_slice_free (FontsetHashKey, key);
}
fontset_hash_key_copy (FontsetHashKey *old)
{
FontsetHashKey *key = g_slice_new (FontsetHashKey);
-
+
key->fontmap = old->fontmap;
key->matrix = old->matrix;
key->language = old->language;
old->context_key);
else
key->context_key = NULL;
-
+
return key;
}
if (key->context_key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
-
+
g_slice_free (FontHashKey, key);
}
font_hash_key_copy (FontHashKey *old)
{
FontHashKey *key = g_slice_new (FontHashKey);
-
+
key->fontmap = old->fontmap;
key->matrix = old->matrix;
key->pattern = old->pattern;
old->context_key);
else
key->context_key = NULL;
-
+
return key;
}
{
key->fontmap = fcfontmap;
get_context_matrix (context, &key->matrix);
-
+
if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
key->context_key = (gpointer)PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
else
font_hash_key_for_context (fcfontmap, context, &key);
key.pattern = fcfont->font_pattern;
-
+
key_copy = font_hash_key_copy (&key);
_pango_fc_font_set_context_key (fcfont, key_copy->context_key);
fcfont->matrix = key.matrix;
-
+
g_hash_table_insert (priv->font_hash, key_copy, fcfont);
}
key.matrix = fcfont->matrix;
key.pattern = fcfont->font_pattern;
key.context_key = _pango_fc_font_get_context_key (fcfont);
-
+
g_hash_table_remove (priv->font_hash, &key);
fcfont->fontmap = NULL;
_pango_fc_font_set_context_key (fcfont, NULL);
GHashTable *temp_family_hash;
fontset = FcFontList (NULL, pat, os);
-
+
FcPatternDestroy (pat);
FcObjectSetDestroy (os);
-
+
priv->families = g_new (PangoFcFamily *, fontset->nfont + 3); /* 3 standard aliases */
temp_family_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
FcChar8 *s;
FcResult res;
int spacing;
-
+
res = FcPatternGetString (fontset->fonts[i], FC_FAMILY, 0, (FcChar8 **) &s);
g_assert (res == FcResultMatch);
g_assert (res == FcResultMatch || res == FcResultNoMatch);
if (res == FcResultNoMatch)
spacing = FC_PROPORTIONAL;
-
+
if (!is_alias_family (s) && !g_hash_table_lookup (temp_family_hash, s))
{
PangoFcFamily *temp_family = create_family (fcfontmap, (gchar *)s, spacing);
priv->families[count++] = create_family (fcfontmap, "Sans", FC_PROPORTIONAL);
priv->families[count++] = create_family (fcfontmap, "Serif", FC_PROPORTIONAL);
priv->families[count++] = create_family (fcfontmap, "Monospace", FC_MONO);
-
+
priv->n_families = count;
}
if (n_families)
*n_families = priv->n_families;
-
+
if (families)
*families = g_memdup (priv->families, priv->n_families * sizeof (PangoFontFamily *));
}
static int
pango_fc_convert_weight_to_fc (PangoWeight pango_weight)
{
-#ifdef FC_WEIGHT_ULTRABOLD
+#ifdef FC_WEIGHT_ULTRABOLD
/* fontconfig 2.1 only had light/medium/demibold/bold/black */
if (pango_weight < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2)
return FC_WEIGHT_ULTRALIGHT;
return FC_WEIGHT_BOLD;
else
return FC_WEIGHT_BLACK;
-#endif
+#endif
}
static int
NULL);
families = g_strsplit (pango_font_description_get_family (description), ",", -1);
-
+
for (i = 0; families[i]; i++)
FcPatternAddString (pattern, FC_FAMILY, families[i]);
GEnumValue *value = g_enum_get_value (get_gravity_class (), gravity);
FcPatternAddString (pattern, PANGO_FC_GRAVITY, value->value_nick);
}
-
+
return pattern;
}
if (priv->closed)
return NULL;
-
+
fcfont = pango_fc_font_map_lookup (fcfontmap, context, match);
if (fcfont)
return g_object_ref (fcfont);
-
+
class = PANGO_FC_FONT_MAP_GET_CLASS (fontmap);
if (class->create_font)
if (pango_matrix)
{
FcMatrix fc_matrix;
-
+
/* Fontconfig has the Y axis pointing up, Pango, down.
*/
fc_matrix.xx = pango_matrix->xx;
fc_matrix.xy = - pango_matrix->xy;
fc_matrix.yx = - pango_matrix->yx;
fc_matrix.yy = pango_matrix->yy;
-
+
pattern = FcPatternDuplicate (match);
FcPatternAddMatrix (pattern, FC_MATRIX, &fc_matrix);
}
else
pattern = match;
-
+
fcfont = PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->new_font (fcfontmap, pattern);
if (pango_matrix)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
FcPattern *old_pattern;
-
+
if (!priv->pattern_hash)
priv->pattern_hash =
g_hash_table_new_full ((GHashFunc)pango_fc_pattern_hash,
(GEqualFunc)pango_fc_pattern_equal,
(GDestroyNotify)FcPatternDestroy, NULL);
-
+
old_pattern = g_hash_table_lookup (priv->pattern_hash, pattern);
if (old_pattern)
{
{
if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_resolution)
return PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_resolution (fcfontmap, context);
-
+
if (fcfontmap->priv->dpi < 0)
{
FcResult result = FcResultNoMatch;
result = FcPatternGetDouble (tmp, FC_DPI, 0, &fcfontmap->priv->dpi);
FcPatternDestroy (tmp);
}
-
+
if (result != FcResultMatch)
{
g_warning ("Error getting DPI from fontconfig, using 72.0");
const PangoFontDescription *desc)
{
int size = pango_font_description_get_size (desc);
-
+
if (pango_font_description_get_size_is_absolute (desc))
return size;
else
key.context_key = (gpointer)PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
else
key.context_key = NULL;
-
+
patterns = g_hash_table_lookup (priv->fontset_hash, &key);
if (patterns == NULL)
pattern = pango_fc_make_pattern (desc, language,
scaled_size,
pango_fc_font_map_get_resolution (fcfontmap, context));
-
+
pango_fc_default_substitute (fcfontmap, context, pattern);
font_patterns = FcFontSort (NULL, pattern, FcTrue, NULL, &res);
/* There is no point in proceeding; we'll just get a segfault later
* on, and a bunch more possibly confusing error messages in between.
*/
-
+
/* return NULL; */
exit (1);
}
patterns->patterns[patterns->n_patterns++] = uniquify_pattern (fcfontmap, font_pattern);
}
}
-
+
FcPatternDestroy (pattern);
-
+
FcFontSetSortDestroy (font_patterns);
patterns->key = fontset_hash_key_copy (&key);
gpointer data)
{
*(PangoFont **)data = font;
-
+
return TRUE;
}
if (font)
g_object_ref (font);
-
+
g_object_unref (fontset);
}
-
+
return font;
}
if (patterns->fontset)
g_object_unref (patterns->fontset);
-
+
for (i = 0; i < patterns->n_patterns; i++)
FcPatternDestroy (patterns->patterns[i]);
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
GQueue *cache = priv->fontset_cache;
-
+
if (patterns->cache_link)
{
/* Already in cache, move to head
tmp_patterns->cache_link = NULL;
g_hash_table_remove (priv->fontset_hash, tmp_patterns->key);
}
-
+
patterns->cache_link = g_list_prepend (NULL, patterns);
}
PangoFcPatternSet *patterns = pango_fc_font_map_get_patterns (fontmap, context, desc, language);
PangoFontset *result;
int i;
-
+
if (!patterns)
return NULL;
patterns->fontset = PANGO_FONTSET (simple);
}
-
+
result = g_object_ref (patterns->fontset);
-
+
return result;
}
PangoFcFontMap *fcfontmap)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
-
+
g_hash_table_remove (priv->fontset_hash, patterns->key);
}
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
GQueue *cache = priv->fontset_cache;
-
+
g_list_foreach (cache->head, (GFunc)uncache_patterns, fcfontmap);
g_list_free (cache->head);
cache->head = NULL;
/**
* pango_fc_font_map_cache_clear:
* @fcfontmap: a #PangoFcFontmap
- *
+ *
* Clear all cached information and fontsets for this font map;
* this should be called whenever there is a change in the
* output of the default_substitute() virtual function.
pango_fc_font_map_cache_clear (PangoFcFontMap *fcfontmap)
{
fcfontmap->priv->dpi = -1;
-
+
pango_fc_font_map_clear_fontset_cache (fcfontmap);
}
key_dup->id = key->id;
key_dup->filename = (char *) (key_dup + 1);
strcpy (key_dup->filename, key->filename);
-
+
g_hash_table_insert (priv->coverage_hash,
key_dup, pango_coverage_ref (coverage));
}
PangoFcCoverageKey key;
PangoCoverage *coverage;
FcCharSet *charset;
-
+
/*
* Assume that coverage information is identified by
* a filename/index pair; there shouldn't be any reason
if (FcPatternGetInteger (fcfont->font_pattern, FC_INDEX, 0, &key.id) != FcResultMatch)
return NULL;
-
+
coverage = g_hash_table_lookup (priv->coverage_hash, &key);
if (coverage)
return pango_coverage_ref (coverage);
coverage = _pango_fc_font_map_fc_to_coverage (charset);
pango_fc_font_map_set_coverage (fcfontmap, &key, coverage);
-
+
return coverage;
}
/**
* pango_fc_font_map_create_context:
* @fcfontmap: a #PangoFcFontMap
- *
+ *
* Creates a new context for this fontmap. This function is intended
* only for backend implementations deriving from #PangoFcFontmap;
* it is possible that a backend will store additional information
* needed for correct operation on the #PangoContext after calling
* this function.
- *
- * Return value: a new #PangoContext
+ *
+ * Return value: a new #PangoContext
*
* Since: 1.4
**/
/**
* pango_fc_font_map_shutdown:
* @fcfontmap: a #PangoFcFontmap
- *
+ *
* Clears all cached information for the fontmap and marks
* all fonts open for the fontmap as dead. (See the shutdown()
* virtual function of #PangoFcFont.) This function might be used
pango_fc_font_map_cache_clear (fcfontmap);
g_hash_table_destroy (priv->fontset_hash);
priv->fontset_hash = NULL;
-
+
g_hash_table_foreach (priv->font_hash, (GHFunc)cleanup_font, NULL);
g_hash_table_destroy (priv->font_hash);
priv->font_hash = NULL;
return PANGO_WEIGHT_BOLD;
else
return PANGO_WEIGHT_ULTRABOLD;
-#endif
+#endif
}
static PangoStyle
* @include_size: if %TRUE, the pattern will include the size from
* the @pattern; otherwise the resulting pattern will be unsized.
* (only %FC_SIZE is examined, not %FC_PIXEL_SIZE)
- *
+ *
* Creates a #PangoFontDescription that matches the specified
* Fontconfig pattern as closely as possible. Many possible Fontconfig
* pattern values, such as %FC_RASTERIZER or %FC_DPI, don't make sense in
* the context of #PangoFontDescription, so will be ignored.
- *
+ *
* Return value: a new #PangoFontDescription. Free with
* pango_font_description_free().
*
PangoStretch stretch;
double size;
PangoGravity gravity;
-
+
FcChar8 *s;
int i;
FcResult res;
g_assert (res == FcResultMatch);
pango_font_description_set_family (desc, (gchar *)s);
-
+
if (FcPatternGetInteger (pattern, FC_SLANT, 0, &i) == FcResultMatch)
style = pango_fc_convert_slant_to_pango (i);
else
weight = pango_fc_convert_weight_to_pango (i);
else
weight = PANGO_WEIGHT_NORMAL;
-
+
pango_font_description_set_weight (desc, weight);
#ifdef FC_WIDTH
stretch = PANGO_STRETCH_NORMAL;
pango_font_description_set_stretch (desc, stretch);
-
+
pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL);
if (include_size && FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch)
return desc;
}
-/*
+/*
* PangoFcFace
*/
if (strcmp (fcface->style, "Regular") == 0)
return make_alias_description (fcfamily, FALSE, FALSE);
else if (strcmp (fcface->style, "Bold") == 0)
- return make_alias_description (fcfamily, TRUE, FALSE);
+ return make_alias_description (fcfamily, TRUE, FALSE);
else if (strcmp (fcface->style, "Italic") == 0)
return make_alias_description (fcfamily, FALSE, TRUE);
else /* Bold Italic */
return make_alias_description (fcfamily, TRUE, TRUE);
}
-
+
match_pattern = FcPatternBuild (NULL,
FC_FAMILY, FcTypeString, fcfamily->family_name,
FC_STYLE, FcTypeString, fcface->style,
}
FcPatternDestroy (match_pattern);
-
+
return desc;
}
GArray *size_array;
double size, dpi = -1.0;
int i, size_i;
-
+
size_array = g_array_new (FALSE, FALSE, sizeof (int));
for (i = 0; i < fontset->nfont; i++)
{
if (dpi < 0)
dpi = pango_fc_font_map_get_resolution (fcface->family->fontmap, NULL);
-
+
size_i = (int) (PANGO_SCALE * size * 72.0 / dpi);
g_array_append_val (size_array, size_i);
}
}
g_array_sort (size_array, compare_ints);
-
+
if (size_array->len == 0)
{
*n_sizes = 0;
{
PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family);
- return fcfamily->spacing == FC_MONO ||
+ return fcfamily->spacing == FC_MONO ||
#ifdef FC_DUAL
fcfamily->spacing == FC_DUAL ||
#endif
(GInstanceInitFunc) NULL,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FACE,
I_("PangoFcFace"),
&object_info, 0);
}
-
+
return object_type;
}
PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family);
PangoFcFontMap *fcfontmap = fcfamily->fontmap;
PangoFcFontMapPrivate *priv = fcfontmap->priv;
-
+
if (fcfamily->n_faces < 0)
{
FcFontSet *fontset;
int i;
-
+
if (is_alias_family (fcfamily->family_name) || priv->closed)
{
fcfamily->n_faces = 4;
else
{
FcObjectSet *os = FcObjectSetBuild (FC_STYLE, FC_WEIGHT, FC_SLANT, NULL);
- FcPattern *pat = FcPatternBuild (NULL,
+ FcPattern *pat = FcPatternBuild (NULL,
FC_FAMILY, FcTypeString, fcfamily->family_name,
NULL);
FcFontSetDestroy (fontset);
}
}
-
+
if (n_faces)
*n_faces = fcfamily->n_faces;
-
+
if (faces)
*faces = g_memdup (fcfamily->faces, fcfamily->n_faces * sizeof (PangoFontFace *));
}
(GInstanceInitFunc) pango_fc_family_init,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY,
I_("PangoFcFamily"),
&object_info, 0);
}
-
+
return object_type;
}
/**
* PangoFcFontMap:
- *
+ *
* #PangoFcFontMap is a base class for font map implementations
* using the Fontconfig and FreeType libraries. To create a new
* backend using Fontconfig and FreeType, you derive from this class
double (*get_resolution) (PangoFcFontMap *fcfontmap,
PangoContext *context);
-
+
gconstpointer (*context_key_get) (PangoFcFontMap *fcfontmap,
PangoContext *context);
gpointer (*context_key_copy) (PangoFcFontMap *fcfontmap,
gboolean (*context_key_equal) (PangoFcFontMap *fcfontmap,
gconstpointer key_a,
gconstpointer key_b);
-
+
void (*context_substitute) (PangoFcFontMap *fontmap,
PangoContext *context,
FcPattern *pattern);
* PangoFcDecoderFindFunc:
* @pattern: a fully resolved #FcPattern specifying the font on the system
* @user_data: user data passed to pango_fc_font_map_add_decoder_find_func()
- *
+ *
* Callback function passed to pango_fc_font_map_add_decoder_find_func().
- *
+ *
* Return value: a new reference to a custom decoder for this pattern,
* or %NULL if the default decoder handling should be used.
**/
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
PangoFcFontMapClass *fcfontmap_class = PANGO_FC_FONT_MAP_CLASS (class);
-
+
gobject_class->finalize = pango_ft2_font_map_finalize;
fcfontmap_class->default_substitute = _pango_ft2_font_map_default_substitute;
fcfontmap_class->new_font = pango_ft2_font_map_new_font;
pango_ft2_font_map_finalize (GObject *object)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (object);
-
+
if (ft2fontmap->renderer)
g_object_unref (ft2fontmap->renderer);
/**
* pango_ft2_font_map_new:
- *
+ *
* Create a new #PangoFT2FontMap object; a fontmap is used
* to cache information about available fonts, and holds
* certain global parameters such as the resolution and
* the default substitute function (see
* pango_ft2_font_map_set_default_substitute()).
- *
+ *
* Return value: the newly created fontmap object. Unref
* with g_object_unref() when you are finished with it.
*
{
PangoFT2FontMap *ft2fontmap;
FT_Error error;
-
+
/* Make sure that the type system is initialized */
g_type_init ();
-
+
ft2fontmap = g_object_new (PANGO_TYPE_FT2_FONT_MAP, NULL);
-
+
error = FT_Init_FreeType (&ft2fontmap->library);
if (error != FT_Err_Ok)
g_critical ("pango_ft2_font_map_new: Could not initialize freetype");
* on #FcPattern objects.
* @data: data to pass to @func
* @notify: function to call when @data is no longer used.
- *
+ *
* Sets a function that will be called to do final configuration
* substitution on a #FcPattern before it is used to load
* the font. This function can be used to do things like set
fontmap->substitute_func = func;
fontmap->substitute_data = data;
fontmap->substitute_destroy = notify;
-
+
pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (fontmap));
}
/**
* pango_ft2_font_map_substitute_changed:
* @fontmap: a #PangoFT2Fontmap
- *
+ *
* Call this function any time the results of the
* default substitution function set with
* pango_ft2_font_map_set_default_substitute() change.
/**
* pango_ft2_font_map_set_resolution:
- * @fontmap: a #PangoFT2Fontmap
+ * @fontmap: a #PangoFT2Fontmap
* @dpi_x: dots per inch in the X direction
* @dpi_y: dots per inch in the Y direction
- *
+ *
* Sets the horizontal and vertical resolutions for the fontmap.
*
* Since: 1.2
double dpi_y)
{
g_return_if_fail (PANGO_FT2_IS_FONT_MAP (fontmap));
-
+
fontmap->dpi_x = dpi_x;
fontmap->dpi_y = dpi_y;
/**
* pango_ft2_font_map_create_context:
* @fontmap: a #PangoFT2Fontmap
- *
+ *
* Create a #PangoContext for the given fontmap.
- *
+ *
* Return value: the newly created context; free with g_object_unref().
*
* Since: 1.2
pango_ft2_font_map_create_context (PangoFT2FontMap *fontmap)
{
g_return_val_if_fail (PANGO_FT2_IS_FONT_MAP (fontmap), NULL);
-
+
return pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fontmap));
}
* pango_ft2_get_context:
* @dpi_x: the horizontal DPI of the target device
* @dpi_y: the vertical DPI of the target device
- *
+ *
* Retrieves a #PangoContext for the default PangoFT2 fontmap
* (see pango_ft2_fontmap_get_for_display()) and sets the resolution
* for the default fontmap to @dpi_x by @dpi_y.
*
* Use of this function is deprecated; see pango_ft2_fontmap_create_context()
* instead.
- *
+ *
* Return value: the new #PangoContext
**/
PangoContext *
pango_ft2_get_context (double dpi_x, double dpi_y)
{
PangoFontMap *fontmap;
-
+
fontmap = pango_ft2_font_map_for_display ();
pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (fontmap), dpi_x, dpi_y);
*
* Returns a #PangoFT2FontMap. This font map is cached and should
* not be freed. If the font map is no longer needed, it can
- * be released with pango_ft2_shutdown_display(). Use of the
+ * be released with pango_ft2_shutdown_display(). Use of the
* global PangoFT2 fontmap is deprecated; use pango_ft2_font_map_new()
* instead.
*
/**
* pango_ft2_shutdown_display:
- *
+ *
* Free the global fontmap. (See pango_ft2_font_map_for_display())
* Use of the global PangoFT2 fontmap is deprecated.
**/
if (pango_ft2_global_fontmap)
{
pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (pango_ft2_global_fontmap));
-
+
g_object_unref (pango_ft2_global_fontmap);
-
+
pango_ft2_global_fontmap = NULL;
}
}
_pango_ft2_font_map_get_library (PangoFontMap *fontmap)
{
PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
-
+
return ft2fontmap->library;
}
/**
* _pango_ft2_font_map_get_renderer:
* @fontmap: a #PangoFT2Fontmap
- *
+ *
* Gets the singleton PangoFT2Renderer for this fontmap.
- *
- * Return value:
+ *
+ * Return value:
**/
PangoRenderer *
_pango_ft2_font_map_get_renderer (PangoFT2FontMap *ft2fontmap)
struct _PangoFT2WarningHistory {
guint get_face : 1;
-};
+};
extern PangoFT2WarningHistory _pango_ft2_warning_history;
}
face = pango_ft2_font_get_face (font);
-
+
if (face)
{
PangoFT2RenderedGlyph *rendered;
{
if ((*s) & (1 << (7 - (ix % 8))))
*d |= 0xff;
-
+
if ((ix % 8) == 7)
s++;
d++;
src += rendered_glyph->bitmap.pitch;
}
break;
-
+
default:
g_warning ("pango_ft2_render: "
"Unrecognized glyph bitmap pixel mode %d\n",
*
* Since: 1.6
*/
-void
+void
pango_ft2_render_layout_subpixel (FT_Bitmap *bitmap,
PangoLayout *layout,
- int x,
+ int x,
int y)
{
PangoContext *context;
renderer = _pango_ft2_font_map_get_renderer (PANGO_FT2_FONT_MAP (fontmap));
pango_ft2_renderer_set_bitmap (PANGO_FT2_RENDERER (renderer), bitmap);
-
+
pango_renderer_draw_layout (renderer, layout, x, y);
}
*
* Render a #PangoLayout onto a FreeType2 bitmap
*/
-void
+void
pango_ft2_render_layout (FT_Bitmap *bitmap,
PangoLayout *layout,
- int x,
+ int x,
int y)
{
pango_ft2_render_layout_subpixel (bitmap, layout, x * PANGO_SCALE, y * PANGO_SCALE);
*
* Since: 1.6
*/
-void
+void
pango_ft2_render_layout_line_subpixel (FT_Bitmap *bitmap,
PangoLayoutLine *line,
- int x,
+ int x,
int y)
{
PangoContext *context;
renderer = _pango_ft2_font_map_get_renderer (PANGO_FT2_FONT_MAP (fontmap));
pango_ft2_renderer_set_bitmap (PANGO_FT2_RENDERER (renderer), bitmap);
-
+
pango_renderer_draw_layout_line (renderer, line, x, y);
}
*
* Render a #PangoLayoutLine onto a FreeType2 bitmap
*/
-void
+void
pango_ft2_render_layout_line (FT_Bitmap *bitmap,
PangoLayoutLine *line,
- int x,
+ int x,
int y)
{
pango_ft2_render_layout_line_subpixel (bitmap, line, x * PANGO_SCALE, y * PANGO_SCALE);
*
* Since: 1.6
**/
-void
+void
pango_ft2_render_transformed (FT_Bitmap *bitmap,
const PangoMatrix *matrix,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y)
{
PangoFontMap *fontmap;
pango_ft2_renderer_set_bitmap (PANGO_FT2_RENDERER (renderer), bitmap);
pango_renderer_set_matrix (renderer, matrix);
-
+
pango_renderer_draw_glyphs (renderer, font, glyphs, x, y);
}
*
* Renders a #PangoGlyphString onto a FreeType2 bitmap.
**/
-void
+void
pango_ft2_render (FT_Bitmap *bitmap,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y)
{
pango_ft2_render_transformed (bitmap, NULL, font, glyphs, x * PANGO_SCALE, y * PANGO_SCALE);
FcChar8 *filename2 = NULL;
gchar *name;
int id;
-
+
sans = FcPatternBuild (NULL,
FC_FAMILY, FcTypeString, "sans",
FC_PIXEL_SIZE, FcTypeDouble, (double)ft2font->size / PANGO_SCALE,
NULL);
-
+
_pango_ft2_font_map_default_substitute (fcfont->fontmap, sans);
matched = FcFontMatch (NULL, sans, &result);
-
+
if (FcPatternGetString (matched, FC_FILE, 0, &filename2) != FcResultMatch)
goto bail1;
-
+
if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != FcResultMatch)
goto bail1;
-
+
error = FT_New_Face (_pango_ft2_font_map_get_library (fcfont->fontmap),
(char *) filename2, id, &ft2font->face);
-
-
+
+
if (error)
{
bail1:
if (FcPatternGetMatrix (fcfont->font_pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
{
FT_Matrix ft_matrix;
-
+
ft_matrix.xx = 0x10000L * fc_matrix->xx;
ft_matrix.yy = 0x10000L * fc_matrix->yy;
ft_matrix.xy = 0x10000L * fc_matrix->xy;
/**
* pango_ft2_font_get_face:
* @font: a #PangoFont
- *
+ *
* Returns the native FreeType2 <type>FT_Face</type> structure used for this #PangoFont.
* This may be useful if you want to use FreeType2 functions directly.
*
* Use pango_fc_font_lock_face() instead; when you are done with a
* face from pango_fc_font_lock_face() you must call
* pango_fc_font_unlock_face().
- *
+ *
* Return value: a pointer to a <type>FT_Face</type> structure, with the size set correctly
**/
FT_Face
if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch)
goto bail0;
-
+
if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
goto bail0;
if (error)
g_warning ("Error in FT_Set_Char_Size: %d", error);
}
-
+
return ft2font->face;
}
G_DEFINE_TYPE (PangoFT2Font, pango_ft2_font, PANGO_TYPE_FC_FONT)
-static void
+static void
pango_ft2_font_init (PangoFT2Font *ft2font)
{
ft2font->face = NULL;
GObjectClass *object_class = G_OBJECT_CLASS (class);
PangoFontClass *font_class = PANGO_FONT_CLASS (class);
PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class);
-
+
object_class->finalize = pango_ft2_font_finalize;
-
+
font_class->get_glyph_extents = pango_ft2_font_get_glyph_extents;
-
+
fc_font_class->lock_face = pango_ft2_font_real_lock_face;
fc_font_class->unlock_face = pango_ft2_font_real_unlock_face;
}
return info;
}
-
+
static void
pango_ft2_font_get_glyph_extents (PangoFont *font,
PangoGlyph glyph,
* @font: a #PangoFont
* @left: the left #PangoGlyph
* @right: the right #PangoGlyph
- *
+ *
* Retrieves kerning information for a combination of two glyphs.
*
* Use pango_fc_font_kern_glyphs() instead.
- *
- * Return value: The amount of kerning (in Pango units) to apply for
+ *
+ * Return value: The amount of kerning (in Pango units) to apply for
* the given combination of glyphs.
**/
int
PangoGlyph right)
{
PangoFcFont *fc_font = PANGO_FC_FONT (font);
-
+
FT_Face face;
FT_Error error;
FT_Vector kerning;
{
PangoFT2Font *font = PANGO_FT2_FONT (data);
PangoFT2GlyphInfo *info = value;
-
+
if (font->glyph_cache_destroy && info->cached_glyph)
(*font->glyph_cache_destroy) (info->cached_glyph);
g_hash_table_foreach_remove (ft2font->glyph_info,
pango_ft2_free_glyph_info_callback, object);
g_hash_table_destroy (ft2font->glyph_info);
-
+
G_OBJECT_CLASS (pango_ft2_font_parent_class)->finalize (object);
}
* @font: a #PangoFT2Font.
* @language: a language tag.
* @returns: a #PangoCoverage.
- *
+ *
* Gets the #PangoCoverage for a #PangoFT2Font. Use pango_font_get_coverage() instead.
**/
PangoCoverage *
/**
* pango_ft2_get_unknown_glyph:
* @font: a #PangoFont
- *
+ *
* Return the index of a glyph suitable for drawing unknown characters with
* @font, or %PANGO_GLYPH_EMPTY if no suitable glyph found.
- *
+ *
* If you want to draw an unknown-box for a character that is not covered
* by the font,
* use PANGO_GET_UNKNOWN_GLYPH() instead.
- *
+ *
* Return value: a glyph index into @font, or %PANGO_GLYPH_EMPTY
**/
PangoGlyph
if (!PANGO_FT2_IS_FONT (font))
return NULL;
-
+
info = pango_ft2_font_get_glyph_info (font, glyph_index, FALSE);
if (info == NULL)
return NULL;
-
+
return info->cached_glyph;
}
if (!PANGO_FT2_IS_FONT (font))
return;
-
+
info = pango_ft2_font_get_glyph_info (font, glyph_index, TRUE);
info->cached_glyph = cached_glyph;
{
if (!PANGO_FT2_IS_FONT (font))
return;
-
+
PANGO_FT2_FONT (font)->glyph_cache_destroy = destroy_notify;
}
/**
* pango_win32_font_cache_free:
* @cache: a #PangoWin32FontCache
- *
+ *
* Frees a #PangoWin32FontCache and all associated memory. All fonts loaded
* through this font cache will be freed along with the cache.
**/
pango_win32_font_cache_free (PangoWin32FontCache *cache)
{
g_return_if_fail (cache != NULL);
-
+
g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
-
+
g_hash_table_destroy (cache->forward);
g_hash_table_destroy (cache->back);
&& lfp1->lfWidth == lfp2->lfWidth
&& lfp1->lfHeight == lfp2->lfHeight);
}
-
+
/**
* pango_win32_font_cache_new:
- *
+ *
* Creates a font cache.
- *
+ *
* Return value: The new font cache. This must be freed with
* pango_win32_font_cache_free().
**/
cache->forward = g_hash_table_new (logfont_hash, logfont_equal);
cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
-
+
cache->mru = NULL;
cache->mru_tail = NULL;
cache->mru_count = 0;
-
+
return cache;
}
* pango_win32_font_cache_load:
* @cache: a #PangoWin32FontCache
* @logfont: a pointer to a LOGFONT structure describing the font to load.
- *
+ *
* Creates a HFONT from a LOGFONT. The
* result may be newly loaded, or it may have been previously
* stored
- *
+ *
* Return value: The font structure, or %NULL if the font could
* not be loaded. In order to free this structure, you must call
* pango_win32_font_cache_unload().
{
UINT smoothing_type;
-#ifndef SPI_GETFONTSMOOTHINGTYPE
+#ifndef SPI_GETFONTSMOOTHINGTYPE
#define SPI_GETFONTSMOOTHINGTYPE 0x200a
#endif
#ifndef FE_FONTSMOOTHINGCLEARTYPE
PING (("Success! hfont=%p", hfont));
break;
}
-
+
/* If we fail, try some similar fonts often found on Windows. */
if (tries == 0)
{
break;
tries++;
}
-
+
if (!hfont)
return NULL;
-
+
entry = g_slice_new (CacheEntry);
entry->logfont = lf;
entry->mru = NULL;
g_hash_table_insert (cache->forward, &entry->logfont, entry);
- g_hash_table_insert (cache->back, entry->hfont, entry);
+ g_hash_table_insert (cache->back, entry->hfont, entry);
}
-
+
if (entry->mru)
{
if (cache->mru_count > 1 && entry->mru->prev)
{
/* Move to the head of the mru list */
-
+
if (entry->mru == cache->mru_tail)
{
cache->mru_tail = cache->mru_tail->prev;
entry->mru->prev->next = entry->mru->next;
entry->mru->next->prev = entry->mru->prev;
}
-
+
entry->mru->next = cache->mru;
entry->mru->prev = NULL;
cache->mru->prev = entry->mru;
else
{
entry->ref_count++;
-
+
/* Insert into the mru list */
-
+
if (cache->mru_count == CACHE_SIZE)
{
CacheEntry *old_entry = cache->mru_tail->data;
-
+
cache->mru_tail = cache->mru_tail->prev;
cache->mru_tail->next = NULL;
* pango_win32_font_cache_unload:
* @cache: a #PangoWin32FontCache
* @hfont: the HFONT to unload
- *
+ *
* Frees a font structure previously loaded with pango_win32_font_cache_load().
**/
void
entry = g_hash_table_lookup (cache->back, hfont);
g_return_if_fail (entry != NULL);
- cache_entry_unref (cache, entry);
+ cache_entry_unref (cache, entry);
}
static void pango_win32_font_map_list_families (PangoFontMap *fontmap,
PangoFontFamily ***families,
int *n_families);
-
+
static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
PangoContext *context,
PangoWin32Face *face,
&& lfp1->lfItalic == lfp2->lfItalic
&& lfp1->lfWeight == lfp2->lfWeight);
}
-
+
static int CALLBACK
pango_win32_inner_enum_proc (LOGFONT *lfp,
TEXTMETRIC *metrics,
LPARAM lParam)
{
PangoWin32FontMap *win32fontmap = (PangoWin32FontMap *)lParam;
-
+
/* Windows generates synthetic vertical writing versions of East
* Asian fonts with @ prepended to their name, ignore them.
*/
return 1;
}
-static gboolean
-first_match (gpointer key,
- gpointer value,
+static gboolean
+first_match (gpointer key,
+ gpointer value,
gpointer user_data)
{
LOGFONT *lfp = (LOGFONT *)key;
LOGFONT *lfp2 = (LOGFONT *)((PangoWin32SizeInfo *)value)->logfonts->data;
gchar *name = (gchar *)user_data;
-
+
if (strcmp (lfp->lfFaceName, name) == 0 && lfp->lfWeight == lfp2->lfWeight)
return TRUE;
return FALSE;
}
}
-static void
+static void
pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
{
LOGFONT logfont;
win32fontmap->size_infos =
g_hash_table_new ((GHashFunc) logfont_nosize_hash, (GEqualFunc) logfont_nosize_equal);
win32fontmap->n_fonts = 0;
-
+
win32fontmap->font_cache = pango_win32_font_cache_new ();
win32fontmap->freed_fonts = g_queue_new ();
memset (&logfont, 0, sizeof (logfont));
logfont.lfCharSet = DEFAULT_CHARSET;
- EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc,
+ EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc,
(LPARAM)win32fontmap, 0);
/* create synthetic italic entries */
fontmap_class->load_font = pango_win32_font_map_load_font;
fontmap_class->list_families = pango_win32_font_map_list_families;
fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_WIN32;
-
+
pango_win32_get_dc ();
for (i = 0; _pango_included_win32_modules[i].list; i++)
{
/* Make sure that the type system is initialized */
g_type_init ();
-
+
if (default_fontmap != NULL)
return PANGO_FONT_MAP (default_fontmap);
default_fontmap = g_object_new (PANGO_TYPE_WIN32_FONT_MAP, NULL);
-
+
return PANGO_FONT_MAP (default_fontmap);
}
/**
* pango_win32_shutdown_display:
- *
+ *
* Free cached resources.
**/
void
pango_win32_font_map_finalize (GObject *object)
{
PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (object);
-
+
g_list_foreach (win32fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_queue_free (win32fontmap->freed_fonts);
-
+
pango_win32_font_cache_free (win32fontmap->font_cache);
G_OBJECT_CLASS (pango_win32_font_map_parent_class)->finalize (object);
int *n_faces)
{
PangoWin32Family *win32family = PANGO_WIN32_FAMILY (family);
-
+
*n_faces = g_slist_length (win32family->font_entries);
if (faces)
{
GSList *tmp_list;
int i = 0;
-
+
*faces = g_new (PangoFontFace *, *n_faces);
tmp_list = win32family->font_entries;
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY,
I_("PangoWin32Family"),
&object_info, 0);
}
-
+
return object_type;
}
if (families)
{
int i = 0;
-
+
*families = g_new (PangoFontFamily *, *n_families);
tmp_list = family_list;
tmp_list = tmp_list->next;
}
}
-
+
g_slist_free (family_list);
}
win32family = g_object_new (PANGO_WIN32_TYPE_FAMILY, NULL);
win32family->family_name = g_strdup (family_name);
win32family->font_entries = NULL;
-
+
g_hash_table_insert (win32fontmap->families, win32family->family_name, win32family);
}
GSList *tmp_list;
g_return_val_if_fail (description != NULL, NULL);
-
+
PING(("name=%s", pango_font_description_get_family (description)));
win32family = g_hash_table_lookup (win32fontmap->families,
if (win32family)
{
PangoWin32Face *best_match = NULL;
-
+
PING (("got win32family"));
tmp_list = win32family->font_entries;
while (tmp_list)
best_match ? best_match->description : NULL,
face->description))
best_match = face;
-
+
tmp_list = tmp_list->next;
}
PangoWin32Font *win32font;
GSList *tmp_list = face->cached_fonts;
int size = pango_font_description_get_size (description);
-
+
if (pango_font_description_get_size_is_absolute (description))
size = (int) 0.5 + (size * win32fontmap->resolution) / PANGO_SCALE;
-
+
PING(("got best match:%s size=%d",face->logfont.lfFaceName,size));
-
+
while (tmp_list)
{
win32font = tmp_list->data;
if (win32font->size == size)
{
PING (("size matches"));
-
+
g_object_ref (win32font);
if (win32font->in_cache)
pango_win32_fontmap_cache_remove (fontmap, win32font);
-
+
return (PangoFont *)win32font;
}
tmp_list = tmp_list->next;
}
-
+
win32font = pango_win32_font_new (fontmap, &face->logfont, size);
if (!win32font)
return NULL;
-
+
win32font->fontmap = fontmap;
win32font->win32face = face;
face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font);
-
+
return (PangoFont *)win32font;
}
if ((hfont = CreateFontIndirect (lfp)) == NULL)
goto fail0;
-
+
if ((oldhfont = SelectObject (pango_win32_hdc, hfont)) == NULL)
goto fail1;
if (!pango_win32_get_name_header (pango_win32_hdc, &header))
goto fail2;
-
+
PING (("%d name records", header.num_records));
for (i = 0; i < header.num_records; i++)
PING(("platform:%d encoding:%d language:%04x name_id:%d",
record.platform_id, record.encoding_id, record.language_id, record.name_id));
-
+
if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
record.platform_id == ISO_PLATFORM_ID)
unicode_ix = i;
name_ix = unicode_ix;
else
goto fail2;
-
+
if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
goto fail2;
-
+
string = g_malloc (record.string_length + 1);
if (GetFontData (pango_win32_hdc, NAME,
header.string_storage_offset + record.string_offset,
string, record.string_length) != record.string_length)
goto fail2;
-
+
string[record.string_length] = '\0';
-
+
if (name_ix == microsoft_ix)
if (record.encoding_id == SYMBOL_ENCODING_ID ||
record.encoding_id == UNICODE_ENCODING_ID)
codeset = "MacRoman";
else /* name_ix == unicode_ix */
codeset = "UCS-4BE";
-
+
name = g_convert (string, record.string_length, "UTF-8", codeset, NULL, &nbytes, NULL);
if (name == NULL)
goto fail2;
fail1:
DeleteObject (hfont);
-
+
fail0:
return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
}
style = PANGO_STYLE_ITALIC;
variant = PANGO_VARIANT_NORMAL;
-
+
/* The PangoWeight values PANGO_WEIGHT_* map exactly do Windows FW_*
* values. Is this on purpose? Quantize the weight to exact
* PANGO_WEIGHT_* values. Is this a good idea?
/* XXX No idea how to figure out the stretch */
stretch = PANGO_STRETCH_NORMAL;
-
+
description = pango_font_description_new ();
pango_font_description_set_family (description, family);
pango_font_description_set_style (description, style);
gint i;
PING(("face=%s,charset=%d,it=%d,wt=%ld,ht=%ld",lfp->lfFaceName,lfp->lfCharSet,lfp->lfItalic,lfp->lfWeight,lfp->lfHeight));
-
+
/* Ignore Symbol fonts (which don't have any Unicode mapping
* table). We could also be fancy and use the PostScript glyph name
* table for such if present, and build a Unicode map by mapping
while (tmp_list)
{
LOGFONT *rover = tmp_list->data;
-
+
/* We know that lfWeight, lfItalic and lfFaceName match. We
* don't check lfHeight and lfWidth, those are used
* when creating a font.
PING(("already have it"));
return;
}
-
+
tmp_list = tmp_list->next;
}
}
}
size_info->logfonts = g_slist_prepend (size_info->logfonts, lfp2);
-
+
PING(("g_slist_length(size_info->logfonts)=%d", g_slist_length(size_info->logfonts)));
win32face = g_object_new (PANGO_WIN32_TYPE_FACE, NULL);
win32face->description = pango_win32_font_description_from_logfont (lfp2);
win32face->cached_fonts = NULL;
-
+
for (i = 0; i < PANGO_WIN32_N_COVERAGES; i++)
win32face->coverages[i] = NULL;
win32face->logfont = *lfp;
* Maybe a memory leak ...
*/
switch (lfp->lfPitchAndFamily & 0xF0)
- {
+ {
case FF_MODERN : /* monospace */
PING(("monospace"));
font_family->is_monospace = TRUE; /* modify before reuse */
PING(("lfp.face=%s,wt=%ld,ht=%ld,size:%d",lfp->lfFaceName,lfp->lfWeight,lfp->lfHeight,size));
win32fontmap = PANGO_WIN32_FONT_MAP (fontmap);
-
+
size_info = g_hash_table_lookup (win32fontmap->size_infos, lfp);
if (!size_info)
if (size != -1)
{
int new_distance = (font_size == 0) ? 0 : abs (font_size - size);
-
+
if (!closest_match ||
new_distance < match_distance ||
(new_distance < PANGO_SCALE && font_size != 0))
if (!win32face->face_name)
{
PangoFontDescription *desc = pango_font_face_describe (face);
-
+
pango_font_description_unset_fields (desc,
PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FACE,
I_("PangoWin32Face"),
&object_info, 0);
}
-
+
return object_type;
}
/* Written by pango_win32_get_hfont: */
HFONT hfont;
- gint tm_ascent;
+ gint tm_ascent;
gint tm_descent;
gint tm_overhang;
guint16 search_range;
guint16 entry_selector;
guint16 range_shift;
-
+
guint16 reserved;
-
+
guint16 arrays[1];
};
struct format_12_cmap
-{
+{
guint16 format;
guint16 reserved;
guint32 length;
if (!win32font->hfont)
{
cache = pango_win32_font_map_get_font_cache (win32font->fontmap);
-
+
win32font->hfont = pango_win32_font_cache_load (cache, &win32font->logfont);
if (!win32font->hfont)
{
win32font->tm_descent = tm.tmDescent;
win32font->tm_ascent = tm.tmAscent;
}
-
+
return win32font->hfont;
}
/**
* pango_win32_get_context:
- *
+ *
* Retrieves a #PangoContext appropriate for rendering with Windows fonts.
- *
+ *
* Return value: the new #PangoContext
**/
PangoContext *
G_DEFINE_TYPE (PangoWin32Font, pango_win32_font, PANGO_TYPE_FONT)
-static void
+static void
pango_win32_font_init (PangoWin32Font *win32font)
{
win32font->size = -1;
/**
* pango_win32_get_dc:
- *
+ *
* Obtains a handle to the Windows device context that is used by Pango.
- *
+ *
* Return value: A handle to the Windows device context that is used by Pango.
**/
HDC
#ifdef PANGO_WIN32_DEBUGGING
if (getenv ("PANGO_WIN32_DEBUG") != NULL)
pango_win32_debug = TRUE;
-#endif
+#endif
}
return pango_win32_hdc;
-}
+}
/**
* pango_win32_get_debug_flag:
*
* Returns whether debugging is turned on.
- *
+ *
* Return value: %TRUE if debugging is turned on.
- *
+ *
* Since: 1.2
*/
gboolean
object_class->finalize = pango_win32_font_finalize;
object_class->dispose = pango_win32_font_dispose;
-
+
font_class->describe = pango_win32_font_describe;
font_class->describe_absolute = pango_win32_font_describe_absolute;
font_class->get_coverage = pango_win32_font_get_coverage;
g_return_val_if_fail (lfp != NULL, NULL);
result = (PangoWin32Font *)g_object_new (PANGO_TYPE_WIN32_FONT, NULL);
-
+
result->fontmap = fontmap;
g_object_ref (fontmap);
*
* Render a #PangoGlyphString onto a Windows DC
*/
-void
+void
pango_win32_render (HDC hdc,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y)
{
HFONT hfont, old_hfont = NULL;
for (i = 0; i < glyphs->num_glyphs; i++)
{
g_print (" %d:%d", glyphs->glyphs[i].glyph, glyphs->glyphs[i].geometry.width);
- if (glyphs->glyphs[i].geometry.x_offset != 0 ||
+ if (glyphs->glyphs[i].geometry.x_offset != 0 ||
glyphs->glyphs[i].geometry.y_offset != 0)
g_print (":%d,%d", glyphs->glyphs[i].geometry.x_offset,
glyphs->glyphs[i].geometry.y_offset);
return;
old_hfont = SelectObject (hdc, hfont);
-
+
glyph_indexes = g_new (guint16, glyphs->num_glyphs);
dX = g_new (INT, glyphs->num_glyphs);
* must have been loaded using a #PangoContext with an identical
* transformation matrix to that passed in to this function.
**/
-void
+void
pango_win32_render_transformed (HDC hdc,
const PangoMatrix *matrix,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y)
{
XFORM xForm;
glyph_index = glyph = 0;
info = g_hash_table_lookup (win32font->glyph_info, GUINT_TO_POINTER (glyph));
-
+
if (!info)
{
info = g_new0 (PangoWin32GlyphInfo, 1);
SelectObject (pango_win32_hdc, hfont);
/* FIXME: (Alex) This constant reuse of pango_win32_hdc is
not thread-safe */
- res = GetGlyphOutlineA (pango_win32_hdc,
+ res = GetGlyphOutlineA (pango_win32_hdc,
glyph_index,
GGO_METRICS | GGO_GLYPH_INDEX,
- &gm,
+ &gm,
0, NULL,
&m);
-
+
if (res == GDI_ERROR)
{
gchar *error = g_win32_error_message (GetLastError ());
PangoWin32MetricsInfo *info = NULL; /* Quiet gcc */
PangoWin32Font *win32font = (PangoWin32Font *)font;
GSList *tmp_list;
-
+
const char *sample_str = pango_language_get_sample_string (language);
-
+
tmp_list = win32font->metrics_by_lang;
while (tmp_list)
{
info = tmp_list->data;
-
+
if (info->sample_str == sample_str) /* We _don't_ need strcmp */
break;
{
HFONT hfont;
PangoFontMetrics *metrics;
-
+
info = g_new (PangoWin32MetricsInfo, 1);
win32font->metrics_by_lang = g_slist_prepend (win32font->metrics_by_lang, info);
{
PangoCoverage *coverage;
TEXTMETRIC tm;
-
+
SelectObject (pango_win32_hdc, hfont);
GetTextMetrics (pango_win32_hdc, &tm);
PangoContext *context;
PangoFontDescription *font_desc;
PangoLayout *layout;
-
+
/* Get the average width of the chars in "0123456789" */
context = pango_win32_get_context ();
pango_context_set_language (context, language);
metrics->strikethrough_position = metrics->ascent / 3;
}
}
-
+
return pango_font_metrics_ref (info->metrics);
}
if (!hfont)
return FALSE;
-
+
if (!SelectObject (hdc, hfont))
{
g_warning ("pango_win32_font_real_select_font: Cannot select font\n");
return FALSE;
}
-
+
return TRUE;
}
/**
* pango_win32_font_logfont:
* @font: a #PangoFont which must be from the Win32 backend
- *
+ *
* Determine the LOGFONT struct for the specified font.
- *
+ *
* Return value: A newly allocated LOGFONT struct. It must be
* freed with g_free().
**/
* pango_win32_font_select_font:
* @font: a #PangoFont from the Win32 backend
* @hdc: a windows device context
- *
+ *
* Selects the font into the specified DC and changes the mapping mode
* and world transformation of the DC appropriately for the font.
* You may want to surround the use of this function with calls
* See pango_win32_font_get_metrics_factor() for information about
* converting from the coordinate space used by this function
* into Pango units.
- *
+ *
* Return value: %TRUE if the operation succeeded.
**/
gboolean
HDC hdc)
{
g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), FALSE);
-
+
return PANGO_WIN32_FONT_GET_CLASS (font)->select_font (font, hdc);
}
pango_win32_font_done_font (PangoFont *font)
{
g_return_if_fail (PANGO_WIN32_IS_FONT (font));
-
+
PANGO_WIN32_FONT_GET_CLASS (font)->done_font (font);
}
/**
* pango_win32_font_get_metrics_factor:
* @font: a #PangoFont from the win32 backend
- *
+ *
* Returns the scale factor from logical units in the coordinate
* space used by pango_win32_font_select_font() to Pango units
* in user space.
- *
+ *
* Return value: factor to multiply logical units by to get Pango
* units.
**/
pango_win32_font_get_metrics_factor (PangoFont *font)
{
g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), 1.);
-
+
return PANGO_WIN32_FONT_GET_CLASS (font)->get_metrics_factor (font);
}
g_slist_foreach (win32font->metrics_by_lang, (GFunc)free_metrics_info, NULL);
g_slist_free (win32font->metrics_by_lang);
-
+
if (win32font->win32face)
pango_win32_font_entry_remove (win32font->win32face, PANGO_FONT (win32font));
-
+
g_hash_table_destroy (win32font->glyph_info);
-
+
g_object_unref (win32font->fontmap);
G_OBJECT_CLASS (pango_win32_font_parent_class)->finalize (object);
desc = pango_font_description_copy (win32font->win32face->description);
pango_font_description_set_size (desc, win32font->size / (PANGO_SCALE / PANGO_WIN32_FONT_MAP (win32font->fontmap)->resolution));
-
+
return desc;
}
desc = pango_font_description_copy (win32font->win32face->description);
pango_font_description_set_absolute_size (desc, win32font->size);
-
+
return desc;
}
{
static guint engine_type_id = 0;
static guint render_type_id = 0;
-
+
if (engine_type_id == 0)
{
engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_WIN32);
}
-
+
return pango_find_map (lang, engine_type_id, render_type_id);
}
{
coverage = pango_coverage_new ();
pango_win32_font_calc_coverage (font, coverage, lang);
-
+
pango_win32_font_entry_set_coverage (win32font->win32face, coverage, lang);
}
* pango_win32_get_unknown_glyph:
* @font: a #PangoFont
* @wc: the Unicode character for which a glyph is needed.
- *
+ *
* Returns the index of a glyph suitable for drawing @wc as an
* unknown character.
*
* Use PANGO_GET_UNKNOWN_GLYPH() instead.
- *
+ *
* Return value: a glyph index into @font
**/
PangoGlyph
* work property the text alignment of the DC should have TA_BASELINE
* and TA_LEFT.
*/
-void
+void
pango_win32_render_layout_line (HDC hdc,
PangoLayoutLine *line,
- int x,
+ int x,
int y)
{
GSList *tmp_list = line->runs;
PangoRectangle overall_rect;
PangoRectangle logical_rect;
PangoRectangle ink_rect;
-
+
int x_off = 0;
pango_layout_line_get_extents (line,NULL, &overall_rect);
-
+
while (tmp_list)
{
HBRUSH oldfg = NULL;
PangoLayoutRun *run = tmp_list->data;
PangoAttrColor fg_color, bg_color;
gboolean fg_set, bg_set;
-
+
tmp_list = tmp_list->next;
pango_win32_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set);
SelectObject (hdc, oldfg);
DeleteObject (brush);
}
-
+
x_off += logical_rect.width;
}
}
*
* Render a #PangoLayoutLine onto an X drawable
*/
-void
+void
pango_win32_render_layout (HDC hdc,
PangoLayout *layout,
- int x,
+ int x,
int y)
{
PangoLayoutIter *iter;
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
-
+
line = pango_layout_iter_get_line_readonly (iter);
-
+
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
-
+
pango_win32_render_layout_line (hdc,
line,
x + PANGO_PIXELS (logical_rect.x),
}
while (pango_layout_iter_next_line (iter));
- pango_layout_iter_free (iter);
+ pango_layout_iter_free (iter);
}
/* This utility function is duplicated here and in pango-layout.c; should it be
if (fg_set)
*fg_set = FALSE;
-
+
if (bg_set)
*bg_set = FALSE;
-
+
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
if (uline)
*uline = ((PangoAttrInt *)attr)->value;
break;
-
+
case PANGO_ATTR_FOREGROUND:
if (fg_color)
*fg_color = *((PangoAttrColor *)attr);
if (fg_set)
*fg_set = TRUE;
-
+
break;
-
+
case PANGO_ATTR_BACKGROUND:
if (bg_color)
*bg_color = *((PangoAttrColor *)attr);
if (bg_set)
*bg_set = TRUE;
-
+
break;
-
+
default:
break;
}
}
}
-static guint
+static guint
get_cmap_offset (HDC hdc,
guint16 encoding_id)
{
return 0;
n_tables = GUINT16_FROM_BE (n_tables);
-
+
table = g_malloc (ENCODING_TABLE_SIZE*n_tables);
-
+
res = GetFontData (hdc, CMAP, CMAP_HEADER_SIZE, table, ENCODING_TABLE_SIZE*n_tables);
if (res != ENCODING_TABLE_SIZE*n_tables)
return 0;
guint16 *tbl, *tbl_end;
struct format_4_cmap *table;
- /* FIXME: Could look here at the CRC for the font in the DC
+ /* FIXME: Could look here at the CRC for the font in the DC
and return a cached copy if the same */
offset = get_cmap_offset (hdc, UNICODE_ENCODING_ID);
g_free (table);
return NULL;
}
-
+
table->format = GUINT16_FROM_BE (table->format);
table->length = GUINT16_FROM_BE (table->length);
table->language = GUINT16_FROM_BE (table->language);
get_end_count (struct format_4_cmap *table)
{
gint32 seg_count = table->seg_count_x_2/2;
- /* Apparently the reseved spot is not reserved for
+ /* Apparently the reseved spot is not reserved for
the end_count array!? */
return (&table->arrays[seg_count*0])-1;
}
static gboolean
-find_segment (struct format_4_cmap *table,
+find_segment (struct format_4_cmap *table,
guint16 wc,
guint16 *segment)
{
guint16 *end_count = get_end_count (table);
guint16 *start_count = get_start_count (table);
static guint last = 0; /* Cache of one */
-
+
if (last < seg_count &&
wc >= start_count[last] &&
wc <= end_count[last])
*segment = last;
return TRUE;
}
-
+
/* Binary search for the segment */
start = 0; /* inclusive */
end = seg_count; /* not inclusive */
- while (start < end)
+ while (start < end)
{
/* Look at middle pos */
i = (start + end)/2;
if (i == start)
{
/* We made no progress. Look if this is the one. */
-
+
if (wc >= start_count[i] &&
wc <= end_count[i])
{
guint32 length;
guint32 *tbl, *tbl_end;
struct format_12_cmap *table;
-
+
offset = get_cmap_offset (hdc, UCS4_ENCODING_ID);
if (offset == 0)
return NULL;
g_free (table);
return NULL;
}
-
+
tbl_end = (guint32 *) ((char *) table + length);
tbl = table->groups;
return table;
}
-
+
static gpointer
font_get_cmap (PangoFont *font)
{
guint16 segment;
guint16 id;
guint16 ch = wc;
-
+
if (wc > 0xFFFF)
return 0;
return TRUE;
}
-
+
gboolean
pango_win32_get_name_record (HDC hdc,
gint i,
if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
record, sizeof (*record)) != sizeof (*record))
return FALSE;
-
+
record->platform_id = GUINT16_FROM_BE (record->platform_id);
record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
record->language_id = GUINT16_FROM_BE (record->language_id);
guint32 i;
PangoWin32CoverageLanguageClass cjkv;
gboolean hide_unihan = FALSE;
-
+
PING(("font:%s lang:%s",
pango_font_description_to_string (pango_font_describe (font)),
pango_language_to_string (lang)));
PING(("no table"));
return;
}
-
+
PING (("coverage:"));
if (win32font->win32face->cmap_format == 4)
{
else
g_print ("%04x:%04x ", start_count[i], end_count[i]);
}
-#endif
+#endif
for (ch = start_count[i]; ch <= end_count[i]; ch++)
if (hide_unihan && CH_IS_UNIHAN_BMP (ch))
pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);
{
if (ch == 0xFFFF)
break;
-
+
id = *(id_range_offset[i]/2 +
(ch - start_count[i]) +
&id_range_offset[i]);
int y);
void pango_win32_render_layout (HDC hdc,
PangoLayout *layout,
- int x,
+ int x,
int y);
void pango_win32_render_transformed (HDC hdc,
const PangoMatrix *matrix,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y);
#ifdef PANGO_ENABLE_ENGINE
* Win32 fonts.
*/
typedef struct _PangoWin32FontCache PangoWin32FontCache;
-
+
PangoWin32FontCache *pango_win32_font_cache_new (void);
void pango_win32_font_cache_free (PangoWin32FontCache *cache);
-
+
HFONT pango_win32_font_cache_load (PangoWin32FontCache *cache,
const LOGFONT *logfont);
void pango_win32_font_cache_unload (PangoWin32FontCache *cache,
struct _PangoXFontCache
{
Display *display;
-
+
GHashTable *forward;
GHashTable *back;
/**
* pango_x_font_cache_free:
* @cache: a #PangoXFontCache
- *
+ *
* Frees a #PangoXFontCache and all associated memory. All fonts loaded
* through this font cache will be freed along with the cache.
**/
pango_x_font_cache_free (PangoXFontCache *cache)
{
g_return_if_fail (cache != NULL);
-
+
g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
-
+
g_hash_table_destroy (cache->forward);
g_hash_table_destroy (cache->back);
/**
* pango_x_font_cache_new:
* @display: an X display.
- *
+ *
* Creates a font cache for the specified display.
- *
+ *
* Return value: The newly allocated #PangoXFontCache, which should be
* freed with pango_x_font_cache_free().
**/
PangoXFontCache *cache;
g_return_val_if_fail (display != NULL, NULL);
-
+
cache = g_new (PangoXFontCache, 1);
cache->display = display;
-
+
cache->forward = g_hash_table_new (g_str_hash, g_str_equal);
cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
-
+
cache->mru = NULL;
cache->mru_tail = NULL;
cache->mru_count = 0;
-
+
return cache;
}
* pango_x_font_cache_load:
* @cache: a #PangoXFontCache
* @xlfd: the X Logical Font Description to load.
- *
+ *
* Loads a #XFontStruct from a X Logical Font Description. The
* result may be newly loaded, or it may have been previously
* stored.
- *
+ *
* Return value: The font structure, or %NULL if the font could
* not be loaded. In order to free this structure, you must call
* pango_x_font_cache_unload().
if (!fs)
return NULL;
-
+
entry = g_new (CacheEntry, 1);
entry->xlfd = g_strdup (xlfd);
entry->mru = NULL;
g_hash_table_insert (cache->forward, entry->xlfd, entry);
- g_hash_table_insert (cache->back, entry->fs, entry);
+ g_hash_table_insert (cache->back, entry->fs, entry);
}
-
+
if (entry->mru)
{
if (cache->mru_count > 1 && entry->mru->prev)
{
/* Move to the head of the mru list */
-
+
if (entry->mru == cache->mru_tail)
{
cache->mru_tail = cache->mru_tail->prev;
entry->mru->prev->next = entry->mru->next;
entry->mru->next->prev = entry->mru->prev;
}
-
+
entry->mru->next = cache->mru;
entry->mru->prev = NULL;
cache->mru->prev = entry->mru;
else
{
entry->ref_count++;
-
+
/* Insert into the mru list */
-
+
if (cache->mru_count == CACHE_SIZE)
{
CacheEntry *old_entry = cache->mru_tail->data;
-
+
cache->mru_tail = cache->mru_tail->prev;
cache->mru_tail->next = NULL;
* pango_x_font_cache_unload:
* @cache: a #PangoXFontCache
* @fs: the font structure to unload
- *
+ *
* Frees a font structure previously loaded with pango_x_font_cache_load().
**/
void
entry = g_hash_table_lookup (cache->back, fs);
g_return_if_fail (entry != NULL);
- cache_entry_unref (cache, entry);
+ cache_entry_unref (cache, entry);
}
XLFD_SPACING = 10,
XLFD_AVERAGE_WIDTH = 11,
XLFD_CHARSET = 12,
- XLFD_NUM_FIELDS
+ XLFD_NUM_FIELDS
} FontField;
struct _PangoXFamily
{
PangoFontFamily parent_instance;
-
+
char *family_name;
GSList *font_entries;
};
struct _PangoXFace
{
PangoFontFace parent_instance;
-
+
char *xlfd;
PangoFontDescription *description;
PangoCoverage *coverage;
(GInstanceInitFunc) pango_x_font_map_init,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_MAP,
I_("PangoXFontMap"),
&object_info, 0);
}
-
+
return object_type;
}
-static void
+static void
pango_x_font_map_init (PangoXFontMap *xfontmap)
{
xfontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
pango_x_font_map_class_init (PangoFontMapClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
-
+
font_map_parent_class = g_type_class_peek_parent (class);
-
+
object_class->finalize = pango_x_font_map_finalize;
class->load_font = pango_x_font_map_load_font;
class->list_families = pango_x_font_map_list_families;
}
registered_displays = g_slist_prepend (registered_displays, display);
-
+
extcodes = XAddExtension (display);
XESetCloseDisplay (display, extcodes->extension, close_display_cb);
}
* pango_x_font_map_for_display:
* @display: an X #Display.
*
- * Returns a #PangoXFontMap for @display. Font maps are cached and should
- * not be freed. If the font map for a display is no longer needed, it can
+ * Returns a #PangoXFontMap for @display. Font maps are cached and should
+ * not be freed. If the font map for a display is no longer needed, it can
* be released with pango_x_shutdown_display().
*
* Return value: a #PangoXFontMap for @display.
int screen;
g_return_val_if_fail (display != NULL, NULL);
-
+
/* Make sure that the type system is initialized */
g_type_init ();
-
+
while (tmp_list)
{
xfontmap = tmp_list->data;
}
xfontmap = g_object_new (PANGO_TYPE_X_FONT_MAP, NULL);
-
+
xfontmap->display = display;
xfontmap->font_cache = pango_x_font_cache_new (display);
xfontmap->freed_fonts = g_queue_new ();
-
+
/* Get a maximum of MAX_FONTS fontnames from the X server.
Use "-*" as the pattern rather than "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" since
the latter may result in fonts being returned which don't actually exist.
if (pango_x_is_xlfd_font_name (xfontnames[i]))
pango_x_insert_font (xfontmap, xfontnames[i]);
}
-
+
XFreeFontNames (xfontnames);
pango_x_font_map_read_aliases (xfontmap);
/**
* pango_x_shutdown_display:
* @display: an X #Display
- *
+ *
* Free cached resources for the given X display structure.
**/
void
pango_x_font_map_finalize (GObject *object)
{
PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (object);
-
+
g_list_foreach (xfontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_queue_free (xfontmap->freed_fonts);
-
+
pango_x_font_cache_free (xfontmap->font_cache);
/* FIXME: Lots more here */
fontmaps = g_list_remove (fontmaps, xfontmap);
-
+
G_OBJECT_CLASS (font_map_parent_class)->finalize (object);
}
if (families)
{
int i = 0;
-
+
*families = g_new (PangoFontFamily *, *n_families);
tmp_list = family_list;
tmp_list = tmp_list->next;
}
}
-
+
g_slist_free (family_list);
}
font_family = g_object_new (PANGO_X_TYPE_FAMILY, NULL);
font_family->family_name = g_strdup (family_name);
font_family->font_entries = NULL;
-
+
g_hash_table_insert (xfontmap->families, font_family->family_name, font_family);
}
if (font_family)
{
PangoXFace *best_match = NULL;
-
+
tmp_list = font_family->font_entries;
while (tmp_list)
{
PangoXFace *font_entry = tmp_list->data;
-
+
if (pango_font_description_better_match (description,
best_match ? best_match->description : NULL,
font_entry->description))
best_match = font_entry;
-
+
tmp_list = tmp_list->next;
}
-
+
if (best_match)
{
GSList *tmp_list = best_match->cached_fonts;
g_object_ref (result);
if (xfont->in_cache)
pango_x_fontmap_cache_remove (fontmap, xfont);
-
+
break;
}
tmp_list = tmp_list->next;
if (!result)
{
PangoXFont *xfont = pango_x_font_new (fontmap, best_match->xlfd, size);
-
+
xfont->fontmap = fontmap;
xfont->xface = best_match;
best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, xfont);
*/
static gboolean error_occurred;
-static int
+static int
ignore_error (Display *d,
XErrorEvent *e)
{
guchar *data;
Window retval = None;
int (*old_handler) (Display *, XErrorEvent *);
-
+
Atom coverage_win_atom = XInternAtom (display,
"PANGO_COVERAGE_WIN",
False);
-
+
XGetWindowProperty (display,
DefaultRootWindow (display),
coverage_win_atom,
False, XA_WINDOW,
&type, &format, &n_items, &bytes_after,
&data);
-
+
if (type == XA_WINDOW)
{
if (format == 32 && n_items == 1 && bytes_after == 0)
retval = *(Atom *)data;
-
+
XFree (data);
}
if (format != 32 || n_items != 1 || bytes_after != 0 ||
*(Atom *)data != retval)
retval = None;
-
+
XFree (data);
}
else
if (!xfontmap->coverage_win)
{
XSetWindowAttributes attr;
-
+
attr.override_redirect = True;
-
+
XSetCloseDownMode (persistant_display, RetainPermanent);
-
- xfontmap->coverage_win =
+
+ xfontmap->coverage_win =
XCreateWindow (persistant_display,
DefaultRootWindow (persistant_display),
-100, -100, 10, 10, 0, 0,
InputOnly, CopyFromParent,
CWOverrideRedirect, &attr);
-
+
XChangeProperty (persistant_display,
DefaultRootWindow (persistant_display),
XInternAtom (persistant_display,
XA_WINDOW,
32, PropModeReplace,
(guchar *)&xfontmap->coverage_win, 1);
-
+
XChangeProperty (persistant_display,
xfontmap->coverage_win,
32, PropModeReplace,
(guchar *)&xfontmap->coverage_win, 1);
}
-
+
XUngrabServer (persistant_display);
-
+
XSync (persistant_display, False);
XCloseDisplay (persistant_display);
}
guchar *data;
*atom = XInternAtom (xfontmap->display, str, False);
-
+
while (tries--)
{
coverage_win = pango_x_get_coverage_win (xfontmap);
-
+
if (!coverage_win)
return NULL;
-
+
old_handler= XSetErrorHandler (ignore_error);
-
+
if (XGetWindowProperty (xfontmap->display,
coverage_win, *atom,
0, G_MAXLONG,
{
if (format == 8 && bytes_after == 0)
result = pango_coverage_from_bytes (data, n_items);
-
+
XSetErrorHandler (old_handler);
XFree (data);
break;
}
}
-
+
return result;
}
gint size;
int tries = 5;
-
+
pango_coverage_to_bytes (coverage, &bytes, &size);
while (tries--)
old_handler = XSetErrorHandler (ignore_error);
error_occurred = False;
-
+
XChangeProperty (xfontmap->display,
coverage_win,
- atom,
+ atom,
XA_STRING,
8, PropModeReplace,
bytes, size);
-
+
XSync (xfontmap->display, False);
XSetErrorHandler (old_handler);
/* Window disappeared out from under us */
XSetErrorHandler (old_handler);
xfontmap->coverage_win = None;
- }
+ }
}
-
+
g_free (bytes);
}
\f
PangoStretch stretch;
const char *p = line_buf->str;
-
+
lineno += lines_read;
if (!pango_skip_space (&p))
xface = g_object_new (PANGO_X_TYPE_FACE, NULL);
xface->xlfd = NULL;
xface->description = pango_font_description_new ();
-
+
g_string_ascii_down (tmp_buf);
pango_font_description_set_family (xface->description, tmp_buf->str);
if (!pango_parse_variant (tmp_buf->str, &variant, TRUE))
goto error;
pango_font_description_set_variant (xface->description, variant);
-
+
if (!pango_scan_string (&p, tmp_buf))
goto error;
if (!pango_parse_weight (tmp_buf->str, &weight, TRUE))
goto error;
pango_font_description_set_weight (xface->description, weight);
-
+
if (!pango_scan_string (&p, tmp_buf))
goto error;
char *trimmed = pango_trim_string (xlfds[i]);
g_free (xlfds[i]);
xlfds[i] = trimmed;
-
+
if (!pango_x_is_xlfd_font_name (xlfds[i]))
{
g_warning ("XLFD '%s' must be complete (14 fields)", xlfds[i]);
files_str = g_strdup ("~/.pangox_aliases:" SYSCONFDIR "/pango/pangox.aliases");
files = pango_split_file_list (files_str);
-
+
n = 0;
while (files[n])
n++;
{
int i = 0;
int field_len = 0;
-
+
while (*fontname)
{
if (*fontname++ == '-')
else
field_len++;
}
-
+
return (i == 14) ? TRUE : FALSE;
}
const char *t1, *t2;
char *p;
int countdown, len, num_dashes;
-
+
if (!fontname)
return NULL;
-
+
/* we assume this is a valid fontname...that is, it has 14 fields */
-
+
countdown = field_num;
t1 = fontname;
while (*t1 && (countdown >= 0))
if (*t1++ == '-')
countdown--;
-
+
num_dashes = (field_num == XLFD_CHARSET) ? 2 : 1;
for (t2 = t1; *t2; t2++)
- {
+ {
if (*t2 == '-' && --num_dashes == 0)
break;
}
-
+
if (t1 != t2)
{
/* Check we don't overflow the buffer */
}
else
strcpy(buffer, "(nil)");
-
+
return buffer;
}
g_free (identifier);
size_info->xlfds = g_slist_prepend (size_info->xlfds, g_strdup (fontname));
-
+
/* Convert the XLFD into a PangoFontDescription */
-
+
family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer);
if (!family_name)
return;
-
+
style = PANGO_STYLE_NORMAL;
if (pango_x_get_xlfd_field (fontname, XLFD_SLANT, slant_buffer))
{
strcpy (slant_buffer, "*");
variant = PANGO_VARIANT_NORMAL;
-
+
weight = PANGO_WEIGHT_NORMAL;
if (pango_x_get_xlfd_field (fontname, XLFD_WEIGHT, weight_buffer))
{
pango_x_make_matching_xlfd (PangoFontMap *fontmap, char *xlfd, const char *charset, int size)
{
PangoXFontMap *xfontmap;
-
+
GSList *tmp_list;
PangoXSizeInfo *size_info;
char *identifier;
char *dash_charset;
xfontmap = PANGO_X_FONT_MAP (fontmap);
-
+
dash_charset = g_strconcat ("-", charset, NULL);
if (!match_end (xlfd, "-*-*") && !match_end (xlfd, dash_charset))
while (tmp_list)
{
char *tmp_xlfd = tmp_list->data;
-
+
if (match_end (tmp_xlfd, dash_charset))
{
int font_size = pango_x_get_size (xfontmap, tmp_xlfd);
int n_dashes = 0;
int target_size;
char *prefix;
-
+
/* OK, we have a match; let's modify it to fit this size and charset */
p = closest_match;
n_dashes++;
p++;
}
-
+
prefix_end = p - 1;
-
+
while (n_dashes < 9)
{
if (*p == '-')
n_dashes++;
p++;
}
-
+
target_size = (int)((double)size / xfontmap->resolution + 0.5);
prefix = g_strndup (closest_match, prefix_end - closest_match);
result = g_strdup_printf ("%s--%d-*-*-*-*-*-%s", prefix, target_size, charset);
if (xfontmap->freed_fonts->tail)
xfontmap->freed_fonts->tail->next = NULL;
}
-
+
xfontmap->freed_fonts->head = g_list_delete_link (xfontmap->freed_fonts->head, link);
xfontmap->freed_fonts->length--;
xfont->in_cache = FALSE;
Atom
-pango_x_fontmap_atom_from_name (PangoFontMap *fontmap,
+pango_x_fontmap_atom_from_name (PangoFontMap *fontmap,
const char *atomname)
{
PangoXFontMap *xfm = PANGO_X_FONT_MAP(fontmap);
found = g_hash_table_lookup (xfm->to_atom_cache, atomname);
- if (found)
+ if (found)
return (Atom)(GPOINTER_TO_UINT(found));
atom = XInternAtom (xfm->display, atomname, FALSE);
- g_hash_table_insert (xfm->to_atom_cache, g_strdup (atomname),
+ g_hash_table_insert (xfm->to_atom_cache, g_strdup (atomname),
(gpointer)atom);
return atom;
G_CONST_RETURN char *
-pango_x_fontmap_name_from_atom (PangoFontMap *fontmap,
+pango_x_fontmap_name_from_atom (PangoFontMap *fontmap,
Atom atom)
{
PangoXFontMap *xfm = PANGO_X_FONT_MAP(fontmap);
found = g_hash_table_lookup (xfm->from_atom_cache, GUINT_TO_POINTER(atom));
- if (found)
+ if (found)
return (const char *)found;
name = XGetAtomName (xfm->display, atom);
return name2;
}
-/*
+/*
* PangoXFace
*/
if (!xface->face_name)
{
PangoFontDescription *desc = pango_font_face_describe (face);
-
+
pango_font_description_unset_fields (desc,
PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
(GInstanceInitFunc) NULL,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FACE,
I_("PangoXFace"),
&object_info, 0);
}
-
+
return object_type;
}
pango_coverage_ref (xface->coverage);
return xface->coverage;
}
-
+
xfont = (PangoXFont *)font;
-
+
xfontmap = (PangoXFontMap *)pango_x_font_map_for_display (xfont->display);
if (xface->xlfd)
{
const char *lang_str = language ? pango_language_to_string (language) : "*";
-
+
char *str = g_strconcat (lang_str, "|", xface->xlfd, NULL);
result = pango_x_get_cached_coverage (xfontmap, str, &atom);
g_free (str);
gunichar wc;
result = pango_coverage_new ();
-
+
shape_map = pango_x_get_shaper_map (language);
engine = (PangoEngineShape *)pango_map_get_engine (shape_map, PANGO_SCRIPT_COMMON);
-
+
for (wc = 0; wc < 65536; wc++)
{
PangoCoverageLevel level;
if (level != PANGO_COVERAGE_NONE)
pango_coverage_set (result, wc, level);
}
-
+
if (atom)
pango_x_store_cached_coverage (xfontmap, atom, result);
}
-
+
if (xface)
{
xface->coverage = result;
pango_coverage_ref (result);
}
-
+
return result;
}
{
GSList *tmp_list;
int i = 0;
-
+
*faces = g_new (PangoFontFace *, *n_faces);
tmp_list = xfamily->font_entries;
(GInstanceInitFunc) NULL,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY,
I_("PangoXFamily"),
&object_info, 0);
}
-
+
return object_type;
}
* of length n_fonts
*/
GHashTable *subfonts_by_charset;
-
+
PangoXSubfontInfo **subfonts;
int n_subfonts;
* in use.
*/
gboolean in_cache;
-
+
PangoXFace *xface; /* Used to remove cached fonts */
};
void pango_x_fontmap_cache_remove (PangoFontMap *fontmap,
PangoXFont *xfont);
-Atom pango_x_fontmap_atom_from_name (PangoFontMap *fontmap,
+Atom pango_x_fontmap_atom_from_name (PangoFontMap *fontmap,
const char *atomname);
const char *pango_x_fontmap_name_from_atom (PangoFontMap *fontmap,
Atom atom);
PangoXSubfont subfont_index)
{
PangoXFont *xfont = (PangoXFont *)font;
-
+
if (subfont_index < 1 || subfont_index > xfont->n_subfonts)
{
g_warning ("Invalid subfont %d", subfont_index);
return NULL;
}
-
+
return xfont->subfonts[subfont_index-1];
}
PangoXFontCache *cache;
cache = pango_x_font_map_get_font_cache (xfont->fontmap);
-
+
info->font_struct = pango_x_font_cache_load (cache, info->xlfd);
if (!info->font_struct)
{
/* Prevent a segfault, but probably not much more */
info->font_struct = pango_x_font_cache_load (cache, "fixed");
}
-
+
info->is_1byte = (info->font_struct->min_byte1 == 0 && info->font_struct->max_byte1 == 0);
info->range_byte1 = info->font_struct->max_byte1 - info->font_struct->min_byte1 + 1;
info->range_byte2 = info->font_struct->max_char_or_byte2 - info->font_struct->min_char_or_byte2 + 1;
{
if (!info->font_struct)
pango_x_make_font_struct (font, info);
-
+
return info->font_struct;
}
/**
* pango_x_get_context:
* @display: an X display (As returned by XOpenDisplay().)
- *
+ *
* Retrieves a #PangoContext appropriate for rendering with X fonts on the
* given display.
- *
+ *
* Return value: the new #PangoContext.
**/
PangoContext *
PangoXContextInfo *info;
int i;
static gboolean registered_modules = FALSE;
-
- g_return_val_if_fail (display != NULL, NULL);
+
+ g_return_val_if_fail (display != NULL, NULL);
if (!registered_modules)
{
registered_modules = TRUE;
-
+
for (i = 0; _pango_included_x_modules[i].list; i++)
pango_module_register (&_pango_included_x_modules[i]);
}
-
+
result = pango_context_new ();
-
+
info = g_new (PangoXContextInfo, 1);
info->get_gc_func = NULL;
info->free_gc_func = NULL;
g_object_set_qdata_full (G_OBJECT (result),
g_quark_from_static_string ("pango-x-info"),
info, (GDestroyNotify)g_free);
-
+
pango_context_set_font_map (result, pango_x_font_map_for_display (display));
return result;
* @context: a #PangoContext.
* @get_gc_func: function called to create a new GC for a given color.
* @free_gc_func: function called to free a GC created with @get_gc_func.
- *
+ *
* Sets the functions that will be used to get GC's in various colors when
* rendering layouts with this context.
**/
PangoFreeGCFunc free_gc_func)
{
PangoXContextInfo *info;
-
+
g_return_if_fail (context != NULL);
info = g_object_get_qdata (G_OBJECT (context),
(GInstanceInitFunc) pango_x_font_init,
NULL /* value_table */
};
-
+
object_type = g_type_register_static (PANGO_TYPE_FONT,
I_("PangoXFont"),
&object_info, 0);
}
-
+
return object_type;
}
-static void
+static void
pango_x_font_init (PangoXFont *xfont)
{
xfont->subfonts_by_charset = g_hash_table_new (g_str_hash, g_str_equal);
PangoFontClass *font_class = PANGO_FONT_CLASS (class);
parent_class = g_type_class_peek_parent (class);
-
+
object_class->finalize = pango_x_font_finalize;
object_class->dispose = pango_x_font_dispose;
-
+
font_class->describe = pango_x_font_describe;
font_class->get_coverage = pango_x_font_get_coverage;
font_class->find_shaper = pango_x_font_find_shaper;
g_return_val_if_fail (spec != NULL, NULL);
result = g_object_new (PANGO_TYPE_X_FONT, NULL);
-
+
result->fontmap = fontmap;
g_object_ref (fontmap);
result->display = pango_x_fontmap_get_display (fontmap);
g_return_val_if_fail (display != NULL, NULL);
g_return_val_if_fail (spec != NULL, NULL);
-
+
result = pango_x_font_new (pango_x_font_map_for_display (display), spec, -1);
return (PangoFont *)result;
} \
} G_STMT_END
-
+
/**
* pango_x_render:
* @display: the X display.
*
* Renders a #PangoGlyphString onto an X drawable.
*/
-void
+void
pango_x_render (Display *display,
Drawable d,
GC gc,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y)
{
Font old_fid = None;
g_return_if_fail (display != NULL);
g_return_if_fail (glyphs != NULL);
-
+
for (i=0; i<glyphs->num_glyphs; i++)
{
PangoGlyph glyph = glyphs->glyphs[i].glyph;
glyph_x >= -16384 && glyph_x <= 32767 &&
glyph_y >= -16384 && glyph_y <= 32767))
goto next_glyph;
-
+
if ((glyph & PANGO_GLYPH_UNKNOWN_FLAG) == 0)
{
guint16 index = PANGO_X_GLYPH_INDEX (glyph);
guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyph);
PangoXSubfontInfo *subfont;
-
+
subfont = pango_x_find_subfont (font, subfont_index);
if (subfont)
{
fs = pango_x_get_font_struct (font, subfont);
if (!fs)
continue;
-
+
if (fs->fid != old_fid)
{
FLUSH;
int baseline;
int stroke_thick;
gunichar wc;
-
+
unknown_glyph:
FLUSH;
baseline = glyph_y;
stroke_thick = MAX ((int) (0.5 + 0.075 * (y2 - y1)), 1);
-
+
if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)
wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG);
else
baseline - stroke_thick + (stroke_thick - tmp_height) / 2,
arrow_x,
baseline - stroke_thick + (stroke_thick - tmp_height) / 2 + tmp_height - 1);
-
+
if ((arrow_x - x1 - hborder) % 2 == 1)
tmp_height += 2;
}
XFillRectangle (display, d, gc,
x1, y2 - stroke_thick,
x2 - x1, stroke_thick);
-
+
break;
}
}
gunichar wc;
gdouble width_factor;
int w;
-
+
if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)
wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG);
else
wc = 0;
-
+
switch (wc)
{
case '\n':
width_factor = 1.0;
}
}
-
+
metrics = pango_font_get_metrics (font, NULL);
if (metrics)
{
w = metrics->approximate_char_width * width_factor;
w = PANGO_SCALE * PANGO_PIXELS (w);
-
+
if (ink_rect)
{
ink_rect->x = PANGO_SCALE;
int i;
*val = 0;
-
+
i = 0;
while (i < fs->n_properties)
{
guint8 *embedding_levels;
PangoDirection base_dir = PANGO_DIRECTION_LTR;
gboolean finished = FALSE;
-
+
embedding_levels = pango_log2vis_get_embedding_levels (str, -1, &base_dir);
last_shaper = NULL;
finished = TRUE;
shaper = NULL;
}
-
- if (p > start &&
+
+ if (p > start &&
(finished ||
(shaper != last_shaper || last_level != embedding_levels[i])))
{
analysis.language = language;
analysis.level = last_level;
analysis.extra_attrs = NULL;
-
+
pango_shape (start, p - start, &analysis, glyph_str);
for (j = 0; j < glyph_str->num_glyphs; j++)
(*func) (font, &glyph_str->glyphs[j], data);
-
+
start = p;
}
if (!finished)
{
p = g_utf8_next_char (p);
-
+
last_shaper = shaper;
last_level = embedding_levels[i];
i++;
}
}
-
+
pango_glyph_string_free (glyph_str);
g_free (embedding_levels);
}
GSList *tmp_list = subfonts;
gboolean first = TRUE;
int total_avg_widths = 0;
- int n_avg_widths = 0;
+ int n_avg_widths = 0;
Atom avg_width_atom;
avg_width_atom = pango_x_fontmap_atom_from_name (xfont->fontmap,
"AVERAGE_WIDTH");
-
+
metrics->ascent = 0;
metrics->descent = 0;
-
+
while (tmp_list)
{
PangoXSubfontInfo *subfont = pango_x_find_subfont (font, GPOINTER_TO_UINT (tmp_list->data));
-
+
if (subfont)
{
XFontStruct *fs = pango_x_get_font_struct (font, subfont);
gint avg_width = 0;
-
+
if (fs)
{
if (first)
avg_width = PANGO_SCALE * ((fs->min_bounds.width + fs->max_bounds.width) / 2);
}
}
-
+
if (avg_width)
{
total_avg_widths += avg_width;
}
else
g_warning ("Invalid subfont %d in get_font_metrics_from_subfonts", GPOINTER_TO_UINT (tmp_list->data));
-
+
tmp_list = tmp_list->next;
}
PangoFontMetrics *metrics)
{
GSList *subfonts = NULL;
-
+
itemize_string_foreach (font, language, str, get_subfonts_foreach, &subfonts);
get_font_metrics_from_subfonts (font, subfonts, metrics);
g_slist_free (subfonts);
const char *str)
{
int width = 0;
-
+
itemize_string_foreach (font, language, str, average_width_foreach, &width);
return width;
PangoXMetricsInfo *info = NULL; /* Quiet gcc */
PangoXFont *xfont = (PangoXFont *)font;
GSList *tmp_list;
-
+
const char *sample_str = pango_language_get_sample_string (language);
-
+
tmp_list = xfont->metrics_by_lang;
while (tmp_list)
{
info = tmp_list->data;
-
+
if (info->sample_str == sample_str) /* We _don't_ need strcmp */
break;
info->metrics = metrics;
}
-
+
return pango_font_metrics_ref (info->metrics);
}
for (p = xlfd; *p; p++)
if (*p == '-')
ndashes++;
-
+
if (ndashes == 14) /* Complete XLFD */
{
if (match_end (xlfd, "-*-*"))
{
PangoXFont *xfont = (PangoXFont *)font;
PangoXSubfontInfo *info;
-
+
info = g_new (PangoXSubfontInfo, 1);
-
+
info->xlfd = g_strdup (xlfd);
info->font_struct = NULL;
xfont->n_subfonts++;
-
+
if (xfont->n_subfonts > xfont->max_subfonts)
{
xfont->max_subfonts *= 2;
xfont->subfonts = g_renew (PangoXSubfontInfo *, xfont->subfonts, xfont->max_subfonts);
}
-
+
xfont->subfonts[xfont->n_subfonts - 1] = info;
-
+
return xfont->n_subfonts;
}
* the result must be freed using g_free().
* @subfont_charsets: location to store a pointer to an array of subfont IDs for each found subfont;
* the result must be freed using g_free().
- *
+ *
* Lists the subfonts of a given font. The result is ordered first by charset,
* and then within each charset, by the order of fonts in the font specification.
*
- * Return value: length of the arrays stored in @subfont_ids and
+ * Return value: length of the arrays stored in @subfont_ids and
* @subfont_charsets.
**/
int
g_return_val_if_fail (n_charsets == 0 || charsets != NULL, 0);
fontmap = pango_x_font_map_for_display (xfont->display);
-
+
subfont_lists = g_new (PangoXSubfont *, n_charsets);
for (j=0; j<n_charsets; j++)
if (!subfont_lists[j])
{
subfont_lists[j] = g_new (PangoXSubfont, xfont->n_fonts);
-
+
for (i = 0; i < xfont->n_fonts; i++)
{
PangoXSubfont subfont = 0;
if (xfont->size == -1)
{
xlfd = name_for_charset (xfont->fonts[i], charsets[j]);
-
+
if (xlfd)
{
int count;
char **names = XListFonts (xfont->display, xlfd, 1, &count);
if (count > 0)
subfont = pango_x_insert_subfont (font, names[0]);
-
+
XFreeFontNames (names);
g_free (xlfd);
}
g_free (xlfd);
}
}
-
+
subfont_lists[j][i] = subfont;
}
* @font: a #PangoFont which must be from the X backend.
* @glyph: the index of a glyph in the font. (Formed
* using the #PANGO_X_MAKE_GLYPH macro)
- *
+ *
* Checks if the given glyph is present in a X font.
- *
+ *
* Return value: %TRUE if the glyph is present.
**/
gboolean
subfont = pango_x_find_subfont (font, subfont_index);
if (!subfont)
return FALSE;
-
+
cs = pango_x_get_per_char (font, subfont, char_index);
if (cs && (cs->lbearing != cs->rbearing || cs->width != 0))
* pango_x_font_subfont_xlfd:
* @font: a #PangoFont which must be from the X backend.
* @subfont_id: the id of a subfont within the font.
- *
+ *
* Determines the X Logical Font Description for the specified
* subfont.
- *
+ *
* Return value: A newly-allocated string containing the XLFD for the
* subfont. This string must be freed with g_free().
**/
g_slist_foreach (xfont->metrics_by_lang, (GFunc)free_metrics_info, NULL);
g_slist_free (xfont->metrics_by_lang);
-
+
if (xfont->xface)
pango_x_face_remove (xfont->xface, (PangoFont *)xfont);
{
static guint engine_type_id = 0;
static guint render_type_id = 0;
-
+
if (engine_type_id == 0)
{
engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_X);
}
-
+
return pango_find_map (language, engine_type_id, render_type_id);
}
byte1 = (int)(char_index / 256) - fs->min_byte1;
if (byte1 < 0 || byte1 >= subfont->range_byte1)
return NULL;
-
+
byte2 = (int)(char_index % 256) - fs->min_char_or_byte2;
if (byte2 < 0 || byte2 >= subfont->range_byte2)
return NULL;
index = byte1 * subfont->range_byte2 + byte2;
}
-
+
if (fs->per_char)
return &fs->per_char[index];
else
subfont = pango_x_find_subfont (font, subfont_index);
if (!subfont)
return FALSE;
-
+
cs = pango_x_get_per_char (font, subfont, char_index);
if (cs && (cs->lbearing != cs->rbearing || cs->width != 0))
if (charstruct_return)
*charstruct_return = cs;
-
+
return TRUE;
}
else
/**
* pango_x_get_unknown_glyph:
* @font: a #PangoFont.
- *
+ *
* Returns the index of a glyph suitable for drawing unknown characters;
* you should generally use PANGO_GET_UNKNOWN_GLYPH() instead,
* since that may return a glyph that provides a better representation
* of a particular char. (E.g., by showing hex digits, or a glyph
* representative of a certain Unicode range.)
- *
+ *
* Return value: a glyph index into @font.
**/
PangoGlyph
*
* Renders a #PangoLayoutLine onto an X drawable.
*/
-void
+void
pango_x_render_layout_line (Display *display,
Drawable drawable,
GC gc,
PangoLayoutLine *line,
- int x,
+ int x,
int y)
{
GSList *tmp_list = line->runs;
PangoXContextInfo *info =
g_object_get_qdata (G_OBJECT (context),
g_quark_from_static_string ("pango-x-info"));
-
+
int x_off = 0;
pango_layout_line_get_extents (line,NULL, &overall_rect);
-
+
while (tmp_list)
{
PangoUnderline uline = PANGO_UNDERLINE_NONE;
PangoAttrColor fg_color, bg_color;
gboolean fg_set, bg_set;
GC fg_gc;
-
+
tmp_list = tmp_list->next;
pango_x_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set);
else
XDrawLine (display, drawable, gc,
point_x, y + 3, MIN (point_x + 1, end_x), y + 3);
-
+
counter = (counter + 1) % 2;
}
}
if (fg_set && info->get_gc_func && info->free_gc_func)
info->free_gc_func (context, fg_gc);
-
+
x_off += logical_rect.width;
}
}
*
* Renders a #PangoLayout onto an X drawable.
*/
-void
+void
pango_x_render_layout (Display *display,
Drawable drawable,
GC gc,
PangoLayout *layout,
- int x,
+ int x,
int y)
{
PangoLayoutIter *iter;
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
-
+
line = pango_layout_iter_get_line_readonly (iter);
-
+
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
-
+
pango_x_render_layout_line (display, drawable, gc,
line,
x + PANGO_PIXELS (logical_rect.x),
if (fg_set)
*fg_set = FALSE;
-
+
if (bg_set)
*bg_set = FALSE;
-
+
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
if (uline)
*uline = ((PangoAttrInt *)attr)->value;
break;
-
+
case PANGO_ATTR_FOREGROUND:
if (fg_color)
*fg_color = *((PangoAttrColor *)attr);
if (fg_set)
*fg_set = TRUE;
-
+
break;
-
+
case PANGO_ATTR_BACKGROUND:
if (bg_color)
*bg_color = *((PangoAttrColor *)attr);
if (bg_set)
*bg_set = TRUE;
-
+
break;
-
+
default:
break;
}
* Return value: %FALSE, always.
*/
gboolean
-pango_x_apply_ligatures (PangoFont *font,
+pango_x_apply_ligatures (PangoFont *font,
PangoXSubfont subfont_id,
- gunichar **glyphs,
+ gunichar **glyphs,
int *n_glyphs,
- int **clusters)
+ int **clusters)
{
return FALSE;
}
-
+
/**
* pango_x_find_first_subfont:
* @font: A #PangoFont.
* @rfont: A pointer to a #PangoXSubfont.
* @charsets: An array of charsets.
* @n_charsets: The number of charsets in @charsets.
- *
+ *
* Looks for subfonts with the @charset charset,
* in @font, and puts the first one in *@rfont.
*
* Return value: %TRUE if *@rfont now contains a font.
*/
gboolean
-pango_x_find_first_subfont (PangoFont *font,
+pango_x_find_first_subfont (PangoFont *font,
char **charsets,
int n_charsets,
PangoXSubfont *rfont)
* @glyphs: A pointer to a #PangoGlyphString.
* @text: UTF-8 string.
* @n_chars: Number of UTF-8 seqs in @text.
- *
+ *
* This is a simple fallback shaper, that can be used
- * if no subfont that supports a given script is found.
+ * if no subfont that supports a given script is found.
* For every character in @text, it puts the unknown glyph.
*/
-void
-pango_x_fallback_shape (PangoFont *font,
- PangoGlyphString *glyphs,
- const char *text,
- int n_chars)
+void
+pango_x_fallback_shape (PangoFont *font,
+ PangoGlyphString *glyphs,
+ const char *text,
+ int n_chars)
{
PangoGlyph unknown_glyph = pango_x_get_unknown_glyph (font);
PangoRectangle logical_rect;
const char *p;
int i;
-
+
g_return_if_fail (font);
g_return_if_fail (glyphs);
g_return_if_fail (text);
glyphs->glyphs[i].geometry.width = logical_rect.width;
glyphs->log_clusters[i] = p - text;
-
+
p = g_utf8_next_char (p);
}
}
Drawable drawable,
GC gc,
PangoLayout *layout,
- int x,
+ int x,
int y);
/* API for rendering modules
char *pango_x_font_subfont_xlfd (PangoFont *font,
PangoXSubfont subfont_id);
-
-
-gboolean pango_x_find_first_subfont (PangoFont *font,
+
+
+gboolean pango_x_find_first_subfont (PangoFont *font,
char **charsets,
int n_charsets,
PangoXSubfont *rfont);
-void pango_x_fallback_shape (PangoFont *font,
- PangoGlyphString *glyphs,
- const char *text,
+void pango_x_fallback_shape (PangoFont *font,
+ PangoGlyphString *glyphs,
+ const char *text,
int n_chars);
-gboolean pango_x_apply_ligatures (PangoFont *font,
- PangoXSubfont subfont,
- gunichar **glyphs,
+gboolean pango_x_apply_ligatures (PangoFont *font,
+ PangoXSubfont subfont,
+ gunichar **glyphs,
int *n_glyphs,
int **clusters);
PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class);
object_class->finalize = pango_xft_font_finalize;
-
+
font_class->get_glyph_extents = pango_xft_font_get_glyph_extents;
fc_font_class->lock_face = pango_xft_font_real_lock_face;
* want integer line spacing, underline positions, etc
*/
PANGO_FC_FONT (xfont)->is_hinted = TRUE;
-
+
xfont->xft_font = NULL;
return xfont;
/**
* _pango_xft_font_get_mini_font:
* @xfont: a #PangoXftFont
- *
+ *
* Gets the font used for drawing the digits in the
* missing-character hex squares
- *
+ *
* Return value: the #PangoFont used for the digits; this
* value is associated with the main font and will be freed
* along with the main font.
XGlyphInfo extents;
XftFont *mini_xft;
int new_size;
-
+
_pango_xft_font_map_get_info (fcfont->fontmap, &display, &screen);
context = pango_xft_get_context (display, screen);
pango_font_description_set_family_static (desc, "monospace");
new_size = pango_font_description_get_size (fcfont->description) / 2;
-
+
if (pango_font_description_get_size_is_absolute (fcfont->description))
pango_font_description_set_absolute_size (desc, new_size);
else
pango_font_description_free (desc);
g_object_unref (context);
-
+
mini_xft = xft_font_get_font (xfont->mini_font);
-
+
for (i = 0 ; i < 16 ; i++)
{
char c = i < 10 ? '0' + i : 'A' + i - 10;
height = MAX (height, extents.height);
}
-
+
xfont->mini_width = PANGO_SCALE * width;
xfont->mini_height = PANGO_SCALE * height;
xfont->mini_pad = PANGO_SCALE * MIN (height / 2, MAX ((int)(2.2 * height + 27) / 28, 1));
if (xfont->xft_font)
{
Display *display;
-
+
_pango_xft_font_map_get_info (fcfont->fontmap, &display, NULL);
XftFontClose (display, xfont->xft_font);
}
{
PangoFont *font = PANGO_FONT (xfont);
XftFont *xft_font = xft_font_get_font (font);
-
+
gint cols = (glyph & ~PANGO_GLYPH_UNKNOWN_FLAG) > 0xffff ? 3 : 2;
-
+
_pango_xft_font_get_mini_font (xfont);
-
+
if (ink_rect)
{
ink_rect->x = 0;
ink_rect->width = xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1);
ink_rect->height = xfont->mini_height * 2 + xfont->mini_pad * 5;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
XGlyphInfo extents;
Display *display;
FT_UInt ft_glyph = glyph;
-
+
_pango_xft_font_map_get_info (fcfont->fontmap, &display, NULL);
XftGlyphExtents (display, xft_font, &ft_glyph, 1, &extents);
ink_rect->width = extents.width * PANGO_SCALE;
ink_rect->height = extents.height * PANGO_SCALE;
}
-
+
if (logical_rect)
{
logical_rect->x = 0;
if (!extents)
{
extents = g_slice_new (Extents);
-
+
pango_fc_font_get_raw_extents (PANGO_FC_FONT (xfont),
FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING,
glyph,
GUINT_TO_POINTER (glyph),
extents);
}
-
+
if (ink_rect)
*ink_rect = extents->ink_rect;
XftFont *xft_font;
gboolean size_is_absolute;
double size;
-
+
_pango_xft_font_map_get_info (fcfont->fontmap, &display, &screen);
-
+
size_is_absolute = pango_font_description_get_size_is_absolute (fcfont->description);
size = pango_font_description_get_size (fcfont->description) / PANGO_SCALE;
-
+
xft_font = XftFontOpen (display, screen,
FC_FAMILY, FcTypeString, "sans",
size_is_absolute ? FC_PIXEL_SIZE : FC_SIZE, FcTypeDouble, size,
NULL);
-
+
if (!xft_font)
{
g_warning ("Cannot open fallback font, nothing to do");
gchar *name = pango_font_description_to_string (fcfont->description);
g_warning ("Cannot open font file for font %s", name);
g_free (name);
-
+
load_fallback_font (xfont);
}
}
-
+
return xfont->xft_font;
}
pango_xft_font_real_lock_face (PangoFcFont *font)
{
XftFont *xft_font = xft_font_get_font ((PangoFont *)font);
-
+
return XftLockFace (xft_font);
}
pango_xft_font_real_unlock_face (PangoFcFont *font)
{
XftFont *xft_font = xft_font_get_font ((PangoFont *)font);
-
+
XftUnlockFace (xft_font);
}
gunichar wc)
{
XftFont *xft_font = xft_font_get_font ((PangoFont *)font);
-
+
return XftCharExists (NULL, xft_font, wc);
}
gunichar wc)
{
XftFont *xft_font = xft_font_get_font ((PangoFont *)font);
-
+
return XftCharIndex (NULL, xft_font, wc);
}
pango_xft_font_real_shutdown (PangoFcFont *fcfont)
{
PangoXftFont *xfont = PANGO_XFT_FONT (fcfont);
-
+
if (xfont->xft_font)
{
Display *display;
}
return NULL;
}
-
+
return xft_font_get_font (font);
}
* pango_xft_font_get_glyph:
* @font: a #PangoFont for the Xft backend
* @wc: Unicode codepoint to look up
- *
+ *
* Gets the glyph index for a given Unicode character
* for @font. If you only want to determine
* whether the font has the glyph, use pango_xft_font_has_char().
- *
+ *
* Use pango_fc_font_get_glyph() instead.
*
* Return value: the glyph index, or 0, if the Unicode
* pango_xft_font_has_char:
* @font: a #PangoFont for the Xft backend
* @wc: Unicode codepoint to look up
- *
+ *
* Determines whether @font has a glyph for the codepoint @wc.
- *
+ *
* Use pango_fc_font_has_char() instead.
*
* Return value: %TRUE if @font has the requested codepoint.
Display *display;
int screen;
-
+
/* Function to call on prepared patterns to do final
* config tweaking.
*/
pango_xft_font_map_finalize (GObject *object)
{
PangoXftFontMap *xftfontmap = PANGO_XFT_FONT_MAP (object);
-
+
if (xftfontmap->renderer)
g_object_unref (xftfontmap->renderer);
int screen)
{
GSList *tmp_list;
-
+
tmp_list = fontmaps;
while (tmp_list)
{
PangoXftFontMap *xftfontmap = tmp_list->data;
if (xftfontmap->display == display &&
- xftfontmap->screen == screen)
+ xftfontmap->screen == screen)
return PANGO_FONT_MAP (xftfontmap);
tmp_list = tmp_list->next;
XExtCodes *extcodes)
{
GSList *tmp_list;
-
+
tmp_list = fontmaps;
while (tmp_list)
{
}
registered_displays = g_slist_prepend (registered_displays, display);
-
+
extcodes = XAddExtension (display);
XESetCloseDisplay (display, extcodes->extension, close_display_cb);
}
* pango_xft_get_font_map:
* @display: an X display
* @screen: the screen number of a screen within @display
- *
+ *
* Returns the #PangoXftFontmap for the given display and screen.
* The fontmap is owned by Pango and will be valid until
* the display is closed.
- *
+ *
* Return value: a #PangoFontMap object, owned by Pango.
*
* Since: 1.2
PangoXftFontMap *xftfontmap;
g_return_val_if_fail (display != NULL, NULL);
-
+
fontmap = pango_xft_find_font_map (display, screen);
if (fontmap)
return fontmap;
-
+
/* Make sure that the type system is initialized */
g_type_init ();
xftfontmap = (PangoXftFontMap *)g_object_new (PANGO_TYPE_XFT_FONT_MAP, NULL);
-
+
xftfontmap->display = display;
xftfontmap->screen = screen;
* pango_xft_shutdown_display:
* @display: an X display
* @screen: the screen number of a screen within @display
- *
+ *
* Release any resources that have been cached for the
* combination of @display and @screen. Note that when the
* X display is closed, resources are released automatically,
int screen)
{
PangoFontMap *fontmap;
-
+
fontmap = pango_xft_find_font_map (display, screen);
if (fontmap)
{
fontmaps = g_slist_remove (fontmaps, fontmap);
pango_fc_font_map_shutdown (PANGO_FC_FONT_MAP (fontmap));
-
+
xftfontmap->display = NULL;
g_object_unref (fontmap);
}
-}
+}
/**
* pango_xft_set_default_substitute:
* on #FcPattern objects.
* @data: data to pass to @func
* @notify: function to call when @data is no longer used.
- *
+ *
* Sets a function that will be called to do final configuration
* substitution on a #FcPattern before it is used to load
* the font. This function can be used to do things like set
GDestroyNotify notify)
{
PangoXftFontMap *xftfontmap = (PangoXftFontMap *)pango_xft_get_font_map (display, screen);
-
+
if (xftfontmap->substitute_destroy)
xftfontmap->substitute_destroy (xftfontmap->substitute_data);
xftfontmap->substitute_func = func;
xftfontmap->substitute_data = data;
xftfontmap->substitute_destroy = notify;
-
+
pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (xftfontmap));
}
* pango_xft_substitute_changed:
* @display: an X Display
* @screen: the screen number of a screen within @display
- *
+ *
* Call this function any time the results of the
* default substitution function set with
* pango_xft_set_default_substitute() change.
int screen)
{
PangoXftFontMap *xftfontmap = (PangoXftFontMap *)pango_xft_get_font_map (display, screen);
-
+
pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (xftfontmap));
}
* @screen: an X screen.
*
* Retrieves a #PangoContext appropriate for rendering with
- * Xft fonts on the given screen of the given display.
+ * Xft fonts on the given screen of the given display.
*
- * Return value: the new #PangoContext.
+ * Return value: the new #PangoContext.
**/
PangoContext *
pango_xft_get_context (Display *display,
/**
* _pango_xft_font_map_get_renderer:
* @fontmap: a #PangoXftFontmap
- *
+ *
* Gets the singleton #PangoXFTRenderer for this fontmap.
- *
- * Return value:
+ *
+ * Return value:
**/
PangoRenderer *
_pango_xft_font_map_get_renderer (PangoXftFontMap *xftfontmap)
{
PangoXftFontMap *xftfontmap = PANGO_XFT_FONT_MAP (fcfontmap);
double d;
-
+
FcConfigSubstitute (NULL, pattern, FcMatchPattern);
if (xftfontmap->substitute_func)
xftfontmap->substitute_func (pattern, xftfontmap->substitute_data);
struct _PangoXftWarningHistory {
guint get_font : 1;
-};
+};
extern PangoXftWarningHistory _pango_xft_warning_history;
Picture src_picture;
Picture dest_picture;
-
+
XRenderPictFormat *mask_format;
GArray *trapezoids;
GParamSpec *pspec)
{
PangoXftRenderer *xftrenderer = PANGO_XFT_RENDERER (object);
-
+
switch (prop_id)
{
case PROP_DISPLAY:
xftrenderer->screen = g_value_get_int (value);
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
}
if (pixel_x < -32768 || pixel_x > 32767 ||
pixel_y < -32768 || pixel_y > 32767)
return;
-
+
flush_trapezoids (xftrenderer);
if (!xftrenderer->priv->glyphs)
xftrenderer->priv->glyphs = g_array_new (FALSE, FALSE,
sizeof (XftGlyphSpec));
-
+
if (xftrenderer->priv->glyph_font != font ||
xftrenderer->priv->glyphs->len == MAX_GLYPHS)
{
flush_glyphs (xftrenderer);
-
+
xftrenderer->priv->glyph_font = g_object_ref (font);
}
int row, col;
int cols;
PangoGlyph glyph;
-
+
PangoFont *mini_font = _pango_xft_font_get_mini_font (xfont);
XftFont *mini_xft_font = pango_xft_font_get_font (mini_font);
if (!mini_xft_font)
_pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y);
return;
}
-
+
glyph = gi->glyph & ~PANGO_GLYPH_UNKNOWN_FLAG;
-
+
ys[0] = glyph_y - PANGO_SCALE * xft_font->ascent + PANGO_SCALE * (((xft_font->ascent + xft_font->descent) - (xfont->mini_height * 2 + xfont->mini_pad * 5 + PANGO_SCALE / 2) / PANGO_SCALE) / 2);
ys[1] = ys[0] + 2 * xfont->mini_pad + xfont->mini_height;
ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad;
- xs[0] = glyph_x;
+ xs[0] = glyph_x;
xs[1] = xs[0] + 2 * xfont->mini_pad;
xs[2] = xs[1] + xfont->mini_width + xfont->mini_pad;
xs[3] = xs[2] + xfont->mini_width + xfont->mini_pad;
xs[0], ys[0],
xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1),
xfont->mini_height * 2 + xfont->mini_pad * 5);
-
+
for (row = 0; row < 2; row++)
for (col = 0; col < cols; col++)
{
draw_glyph (renderer, font, gi->glyph, glyph_x, glyph_y);
}
}
-
+
x_off += gi->geometry.width;
}
}
if (!xftrenderer->priv->trapezoids)
xftrenderer->priv->trapezoids = g_array_new (FALSE, FALSE,
sizeof (XTrapezoid));
-
+
if (xftrenderer->draw)
{
if (xftrenderer->priv->trapezoids->len > 0 &&
part);
if (!color)
color = &xftrenderer->priv->default_color;
-
+
xft_color.color.red = color->red;
xft_color.color.green = color->green;
xft_color.color.blue = color->blue;
PANGO_RENDER_PART_FOREGROUND);
if (!color)
color = &xftrenderer->priv->default_color;
-
+
xft_color.color.red = color->red;
xft_color.color.green = color->green;
xft_color.color.blue = color->blue;
PangoRenderer *renderer;
PangoXftRenderer *xftrenderer;
PangoColor pango_color;
-
+
renderer = _pango_xft_font_map_get_renderer (PANGO_XFT_FONT_MAP (fontmap));
xftrenderer = PANGO_XFT_RENDERER (renderer);
-
+
pango_xft_renderer_set_draw (xftrenderer, draw);
pango_color.red = color->color.red;
release_renderer (PangoRenderer *renderer)
{
PangoXftRenderer *xftrenderer = PANGO_XFT_RENDERER (renderer);
-
+
xftrenderer->priv->alpha = 0xffff;
}
*
* Since: 1.8
*/
-void
+void
pango_xft_render_layout (XftDraw *draw,
XftColor *color,
PangoLayout *layout,
- int x,
+ int x,
int y)
{
PangoContext *context;
*
* Since: 1.8
*/
-void
+void
pango_xft_render_layout_line (XftDraw *draw,
XftColor *color,
PangoLayoutLine *line,
- int x,
+ int x,
int y)
{
PangoContext *context;
context = pango_layout_get_context (line->layout);
fontmap = pango_context_get_font_map (context);
renderer = get_renderer (fontmap, draw, color);
-
+
pango_renderer_draw_layout_line (renderer, line, x, y);
release_renderer (renderer);
*
* Since: 1.8
**/
-void
+void
pango_xft_render_transformed (XftDraw *draw,
XftColor *color,
PangoMatrix *matrix,
PangoFont *font,
PangoGlyphString *glyphs,
- int x,
+ int x,
int y)
{
PangoFontMap *fontmap;
renderer = get_renderer (fontmap, draw, color);
pango_renderer_set_matrix (renderer, matrix);
-
+
pango_renderer_draw_glyphs (renderer, font, glyphs, x, y);
release_renderer (renderer);
g_return_if_fail (color != NULL);
g_return_if_fail (PANGO_XFT_IS_FONT (font));
g_return_if_fail (glyphs != NULL);
-
+
pango_xft_render_transformed (draw, color, NULL, font, glyphs,
x * PANGO_SCALE, y * PANGO_SCALE);
}
g_return_if_fail (dest_picture != None);
g_return_if_fail (PANGO_XFT_IS_FONT (font));
g_return_if_fail (glyphs != NULL);
-
+
fontmap = PANGO_FC_FONT (font)->fontmap;
renderer = _pango_xft_font_map_get_renderer (PANGO_XFT_FONT_MAP (fontmap));
pango_xft_renderer_set_pictures (PANGO_XFT_RENDERER (renderer),
src_picture, dest_picture);
pango_renderer_set_matrix (renderer, NULL);
-
+
pango_renderer_draw_glyphs (renderer, font, glyphs, x * PANGO_SCALE, y * PANGO_SCALE);
-
+
pango_xft_renderer_set_pictures (PANGO_XFT_RENDERER (renderer),
None, None);
}
* pango_xft_renderer_new:
* @display: an X display
* @screen: the index of the screen for @display to which rendering will be done
- *
+ *
* Create a new #PangoXftRenderer to allow rendering Pango objects
* with the Xft library. You must call pango_xft_renderer_set_draw() before
* using the renderer.
"display", display,
"screen", screen,
NULL);
-
+
return PANGO_RENDERER (xftrenderer);
}
* pango_xft_renderer_set_draw:
* @xftrenderer: a #PangoXftRenderer
* @draw: a #XftDraw
- *
+ *
* Sets the #XftDraw object that the renderer is drawing to.
* The renderer must not be currently active.
*
* pango_xft_renderer_set_default_color:
* @xftrenderer: a #XftRenderer
* @default_color: the default foreground color
- *
+ *
* Sets the default foreground color for a #XftRenderer.
*
* Since: 1.8
PangoColor *default_color)
{
g_return_if_fail (PANGO_IS_XFT_RENDERER (xftrenderer));
-
+
xftrenderer->priv->default_color = *default_color;
}
*/
struct _PangoXftRenderer
{
- /*< private >*/
+ /*< private >*/
PangoRenderer parent_instance;
Display *display;
* the current color and other attributes for @part
* @composite_glyphs: draw the specified glyphs using
* the current foreground color and other foreground
- * attributes
+ * attributes
*
* The class structure for #PangoXftRenderer
*
*/
struct _PangoXftRendererClass
{
- /*< private >*/
+ /*< private >*/
PangoRendererClass parent_class;
/*< public >*/
while (TRUE)
{
char c = *str++;
-
+
switch (c)
{
case '\0':
GEnumValue *value;
if (!class)
class = g_type_class_ref (PANGO_TYPE_SCRIPT);
-
+
value = g_enum_get_value (class, script);
if (!value)
{
return value->value_nick;
}
-static void
+static void
query_module (const char *dir, const char *name)
{
void (*list) (PangoEngineInfo **engines, gint *n_engines);
path = g_strdup (name);
else
path = g_build_filename (dir, name, NULL);
-
+
module = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
if (!module)
g_printerr ("Cannot load module %s: %s\n", path, g_module_error ());
-
+
if (module &&
GET_SYMBOL (module, "script_engine_list", list) &&
GET_SYMBOL (module, "script_engine_init", init) &&
quote = "";
quoted_path = g_strdup (path);
}
-
+
g_printf ("%s%s%s %s %s %s", quote, quoted_path, quote,
engines[i].id, engines[i].engine_type, engines[i].render_type);
g_free (quoted_path);
{
g_printerr ("%s does not export Pango module API\n", path);
}
-
+
g_free (path);
if (module)
g_module_close (module);
-}
+}
static gboolean
show_version(const char *name,
"Show version numbers", NULL},
{NULL}
};
-
+
context = g_option_context_new ("- [MODULE]...");
g_option_context_add_main_entries (context, entries, NULL);
-
+
if (!g_option_context_parse (context, &argc, &argv, &parse_error))
{
if (parse_error != NULL)
}
exit(1);
}
-
+
g_option_context_free(context);
-
+
g_type_init ();
-
+
g_printf ("# Pango Modules file\n"
"# Automatically generated file, do not edit\n"
"#\n");
{
char **dirs;
int i;
-
+
path = pango_config_key_get ("Pango/ModulesPath");
if (!path)
path = g_build_filename (pango_get_lib_subdirectory (),
if (len > SOEXT_LEN && strcmp (dent + len - SOEXT_LEN, SOEXT) == 0)
query_module (dirs[i], dent);
}
-
+
g_dir_close (dir);
}
}
else
{
cwd = g_get_current_dir ();
-
+
for (i=1; i<argc; i++)
query_module (cwd, argv[i]);
g_free (cwd);
}
-
+
return 0;
}
tmp_list = tmp_list->next;
}
-
+
if (min_level % 2)
{
if (i > level_start_i)
* @analysis: #PangoAnalysis structure from pango_itemize()
* @glyphs: glyph string in which to store results
*
- * Given a segment of text and the corresponding
+ * Given a segment of text and the corresponding
* #PangoAnalysis structure returned from pango_itemize(),
* convert the characters into glyphs. You may also pass
* in only a substring of the item from pango_itemize().
*/
void
-pango_shape (const gchar *text,
- gint length,
+pango_shape (const gchar *text,
+ gint length,
const PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
{
/* If a font has been correctly chosen, but no glyphs are output,
* there's probably something wrong with the shaper. Trying to be
- * informative, we print out the font description, but to not
+ * informative, we print out the font description, but to not
* flood the terminal with zillions of the message, we set a flag
* on the font to only err once per font.
*/
if (!warned_quark)
warned_quark = g_quark_from_static_string ("pango-shaper-warned");
-
+
if (!g_object_get_qdata (G_OBJECT (analysis->font), warned_quark))
{
PangoFontDescription *desc;
static void fail (const char *format, ...)
{
char *str;
-
+
va_list args;
va_start (args, format);
va_end (args);
fprintf (stderr, "Error: %s\n", str);
-
+
g_free (str);
exit (1);
PangoLogAttr *attrs;
int i;
gunichar *ucs4;
-
+
if (!g_utf8_validate (text, -1, NULL))
fail ("Invalid UTF-8 in file");
-
+
len = g_utf8_strlen (text, -1);
attrs = g_new0 (PangoLogAttr, len + 1);
len + 1);
ucs4 = g_utf8_to_ucs4 (text, -1, NULL, NULL, NULL);
-
+
i = 0;
while (i <= len)
{
char buf[7] = { '\0', };
char *loc;
-
+
g_unichar_to_utf8 (ucs4[i], buf);
if (*buf == '\n')
loc = g_strdup ("\\n");
else if (*buf == '\r')
loc = g_strdup ("\\r");
- else
+ else
loc = g_locale_from_utf8 (buf, -1, NULL, NULL, NULL);
-
+
g_print (CHFORMAT " (%s):\t line_break = %d mandatory_break = %d char_break = %d\n"
" \t\t white = %d cursor_position = %d\n"
" \t\t word_start = %d word_end = %d\n"
attrs[i].is_sentence_end);
g_free (loc);
-
+
++i;
}
if (argc < 2)
fail ("must give a filename on the command line");
-
+
if (!g_file_get_contents (argv[1], &text, NULL, NULL))
fail ("Couldn't open sample text file");
-
+
dump_text (text);
g_free (text);
-
+
return 0;
}
{
char *str;
char *line_text;
-
+
va_list args;
va_start (args, format);
va_end (args);
line_text = g_strndup (line_start, line_end - line_start);
-
+
fprintf (stderr, "line %d offset %d char is " CHFORMAT ": %s\n (line is '%s')\n", line, offset, current_wc, str, line_text);
g_free (str);
g_free (line_text);
gunichar next_wc;
GUnicodeType prev_type;
GUnicodeType next_type;
-
+
if (next == end)
return;
offset = 0;
line = 0;
-
+
prev_type = (GUnicodeType) -1;
prev_wc = 0;
line_start = text;
line_end = text;
-
+
while (next_wc != 0)
{
GUnicodeType type;
type = next_type;
current_wc = wc;
-
+
next = g_utf8_next_char (next);
line_end = next;
-
+
if (next >= end)
next_wc = 0;
else
i != 0 ? &attrs[i-1] : NULL,
next_wc != 0 ? &attrs[i+1] : NULL,
data);
-
+
prev_type = type;
prev_wc = wc;
++i;
prev_break_type = g_unichar_break_type (prev_wc);
else
prev_break_type = G_UNICODE_BREAK_UNKNOWN;
-
+
if (wc == '\n')
{
if (prev_wc == '\r')
if (attr->is_line_break)
fail ("line break between \\r and \\n");
}
-
+
if (next_attr && !next_attr->is_line_break)
fail ("no line break after \\n");
}
-
+
if (attr->is_line_break && prev_wc == 0)
fail ("first char in string should not be marked as a line break");
if (attr->is_mandatory_break && !attr->is_line_break)
fail ("mandatory breaks must also be marked as regular breaks");
-
-
+
+
/* FIXME use the break tables from break.c to automatically
* check invariants for each cell in the table. Shouldn't
* be that hard to do.
*/
-
+
if (break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION &&
prev_break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION &&
attr->is_line_break &&
prev_break_type == G_UNICODE_BREAK_ALPHABETIC &&
attr->is_line_break &&
!attr->is_mandatory_break)
- fail ("can't break letter-quotemark sequence");
+ fail ("can't break letter-quotemark sequence");
}
static void
g_free (s);
last = p;
}
-
+
p = g_utf8_next_char (p);
++i;
}
if (!g_utf8_validate (text, -1, NULL))
fail ("Invalid UTF-8 in test text");
-
+
len = g_utf8_strlen (text, -1);
attrs = g_new0 (PangoLogAttr, len + 1);
pango_language_from_string ("C"),
attrs,
len + 1);
-
+
check_line_invariants (text, attrs);
check_sentence_invariants (text, attrs);
check_grapheme_invariants (text, attrs);
#if 0
print_sentences (text, attrs);
#endif
-
+
g_free (attrs);
}
int
-main (int argc, char *argv[])
+main (int argc, char *argv[])
{
gchar *text;
const gchar *srcdir;
srcdir = ".";
filename = g_strdup_printf ("%s/boundaries.utf8", srcdir);
-
+
if (!g_file_get_contents (filename, &text, NULL, NULL))
fail ("Couldn't open sample text file");
-
+
check_invariants (text);
g_free (text);
printf ("testboundaries passed\n");
-
+
return 0;
}
const gchar *spec;
gboolean valid;
guint16 red;
- guint16 green;
+ guint16 green;
guint16 blue;
} ColorSpec;
accepted = pango_color_parse (&color, spec->spec);
if (accepted == spec->valid &&
- (!accepted ||
+ (!accepted ||
(color.red == spec->red &&
color.green == spec->green &&
color.blue == spec->blue)))
{ NULL, 0, 0, 0, 0 }
};
-int
-main (int argc, char *argv[])
+int
+main (int argc, char *argv[])
{
gboolean success;
ColorSpec *spec;
static void
verbose (const char *format, ...)
{
-#ifdef VERBOSE
+#ifdef VERBOSE
va_list vap;
-
+
va_start (vap, format);
vfprintf (stderr, format, vap);
va_end (vap);
-#endif
+#endif
}
#define LAYOUT_WIDTH (80 * PANGO_SCALE)
text = pango_layout_get_text (layout);
num_chars = g_utf8_strlen (text, -1);
-
+
iter = pango_layout_get_iter (layout);
iter_next_ok = TRUE;
index = pango_layout_iter_get_index (iter);
ptr = text + index;
char_str = g_strndup (ptr, g_utf8_next_char (ptr) - ptr);
- verbose ("i=%d (visual), index = %d '%s':\n",
+ verbose ("i=%d (visual), index = %d '%s':\n",
i, index, char_str);
g_free (char_str);
pango_layout_iter_get_char_extents (iter, &extents);
verbose (" char extents: x=%d,y=%d w=%d,h=%d\n",
- extents.x, extents.y,
+ extents.x, extents.y,
extents.width, extents.height);
-
+
run = pango_layout_iter_get_run (iter);
if (run)
pango_layout_iter_get_run_extents(iter, NULL, &run_extents);
offset = run->item->offset;
rtl = run->item->analysis.level%2;
- verbose (" (current run: offset=%d,x=%d,len=%d,rtl=%d)\n",
+ verbose (" (current run: offset=%d,x=%d,len=%d,rtl=%d)\n",
offset, run_extents.x, run->item->length, rtl);
-
+
/* Calculate expected x result using index_to_x */
- pango_glyph_string_index_to_x (run->glyphs,
+ pango_glyph_string_index_to_x (run->glyphs,
(char *)(text + offset), run->item->length,
&run->item->analysis,
index - offset, FALSE, &leading_x);
- pango_glyph_string_index_to_x (run->glyphs,
+ pango_glyph_string_index_to_x (run->glyphs,
(char *)(text + offset), run->item->length,
&run->item->analysis,
index - offset, TRUE, &trailing_x);
-
+
x0 = run_extents.x + MIN (leading_x, trailing_x);
x1 = run_extents.x + MAX (leading_x, trailing_x);
-
- verbose (" (index_to_x ind=%d: expected x=%d, width=%d)\n",
+
+ verbose (" (index_to_x ind=%d: expected x=%d, width=%d)\n",
index - offset, x0, x1 - x0);
g_assert (extents.x == x0);
{
/* We're on a line terminator */
}
-
+
iter_next_ok = pango_layout_iter_next_char (iter);
verbose ("more to go? %d\n", iter_next_ok);
}
g_assert (pango_layout_iter_get_run (iter));
index = pango_layout_iter_get_index (iter);
-
+
pango_layout_iter_get_cluster_extents (iter, NULL, &extents);
-
+
iter_next_ok = pango_layout_iter_next_cluster (iter);
-
+
verbose ("index = %d:\n", index);
verbose (" cluster extents: x=%d,y=%d w=%d,h=%d\n",
- extents.x, extents.y,
+ extents.x, extents.y,
extents.width, extents.height);
verbose ("more to go? %d\n", iter_next_ok);
/* All the clusters on a line should be next to each other and occupy
* the entire line. They advance linearly from left to right */
g_assert (extents.width >= 0);
-
+
if (last_line == line)
g_assert (extents.x == expected_next_x);
- expected_next_x = extents.x + extents.width;
+ expected_next_x = extents.x + extents.width;
last_line = line;
}
-
+
g_assert (!iter_next_ok);
pango_layout_iter_free (iter);
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
+ *
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
for (p = text; *p; p = g_utf8_next_char (p))
{
gunichar ch = g_utf8_get_char (p);
-
+
if (escaped)
{
if (ch == 'u' || ch == 'U')
{
int n_chars = ch == 'u' ? 4 : 8;
int i;
-
+
ch = 0;
for (i = 0; i < n_chars; i++)
{
const char *end;
PangoScript script;
unsigned int i;
-
+
for (i = 0; i < G_N_ELEMENTS(test_data); i++)
{
test_data[i].run_text = unescape (test_data[i].run_text_escaped);
#ifdef VERBOSE
g_print ("Total length: %d\n", all->len);
-#endif
+#endif
pos = all->str;
for (i = 0; i < G_N_ELEMENTS(test_data); i++)
{
char *next_pos = pos + strlen (test_data[i].run_text);
gboolean result;
-
+
pango_script_iter_get_range (iter, &start, &end, &script);
#ifdef VERBOSE
g_print ("Range: %d-%d: %d\n", start - all->str, end - all->str, script);
-#endif
+#endif
ASSERT (start == pos);
ASSERT (end == next_pos);
* Test an empty string.
*/
iter = pango_script_iter_new (all->str, 0);
-
+
pango_script_iter_get_range (iter, &start, &end, &script);
-
+
ASSERT (start == all->str);
ASSERT (end == all->str);
ASSERT (script == PANGO_SCRIPT_COMMON);
ASSERT (!pango_script_iter_next (iter));
-
+
pango_script_iter_free (iter);
/* Cleanup */
-
+
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
g_free (test_data[i].run_text);