Author: fejj
Date: 2007-10-03 13:40:44 -0400 (Wed, 03 Oct 2007)
New Revision: 86824
Modified:
trunk/moon/src/ChangeLog
trunk/moon/src/font.cpp
trunk/moon/src/font.h
trunk/moon/src/mplayer.cpp
trunk/moon/src/text.cpp
trunk/moon/src/text.h
Log:
2007-10-03 Jeffrey Stedfast <[EMAIL PROTECTED]>
* text.cpp: Implemented the Glyphs element.
* font.cpp: Made GlyphMetrics and GlyphInfo structs public for use
with the the Glyphs element implemented in text.cpp.
(GetGlyphInfo): Fixes to allow loading of the index=0 glyph.
(GetGlyphInfoByIndex): New method.
(CreatePattern): If the filename is specified, don't call
FcFontMatch(), simply return the constructed pattern.
Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog 2007-10-03 17:35:36 UTC (rev 86823)
+++ trunk/moon/src/ChangeLog 2007-10-03 17:40:44 UTC (rev 86824)
@@ -1,3 +1,14 @@
+2007-10-03 Jeffrey Stedfast <[EMAIL PROTECTED]>
+
+ * text.cpp: Implemented the Glyphs element.
+
+ * font.cpp: Made GlyphMetrics and GlyphInfo structs public for use
+ with the the Glyphs element implemented in text.cpp.
+ (GetGlyphInfo): Fixes to allow loading of the index=0 glyph.
+ (GetGlyphInfoByIndex): New method.
+ (CreatePattern): If the filename is specified, don't call
+ FcFontMatch(), simply return the constructed pattern.
+
2007-10-02 Chris Toshok <[EMAIL PROTECTED]>
* clock.h, clock.cpp: remove TimeManager::current_fps, it's
Modified: trunk/moon/src/font.cpp
===================================================================
--- trunk/moon/src/font.cpp 2007-10-03 17:35:36 UTC (rev 86823)
+++ trunk/moon/src/font.cpp 2007-10-03 17:40:44 UTC (rev 86824)
@@ -22,6 +22,16 @@
#include FT_OUTLINE_H
+struct GlyphBitmap {
+ cairo_surface_t *surface;
+ unsigned char *buffer;
+ int height;
+ int width;
+ int left;
+ int top;
+};
+
+
static GHashTable *font_cache = NULL;
static bool initialized = false;
static FT_Library libft2;
@@ -121,35 +131,6 @@
}
}
-
-struct GlyphMetrics {
- double horiBearingX;
- double horiBearingY;
- double horiAdvance;
- double vertBearingX;
- double vertBearingY;
- double vertAdvance;
- double height;
- double width;
-};
-
-struct GlyphBitmap {
- cairo_surface_t *surface;
- unsigned char *buffer;
- int height;
- int width;
- int left;
- int top;
-};
-
-struct GlyphInfo {
- uint32_t unichar;
- uint32_t index;
- GlyphMetrics metrics;
- GlyphBitmap *bitmap;
- moon_path *path;
-};
-
static const FT_Matrix invert_y = {
65535, 0,
0, -65535,
@@ -276,7 +257,7 @@
}
double
-TextFont::Kerning (uint32_t left, uint32_t right)
+TextFont::Kerning (gunichar left, gunichar right)
{
FT_Vector kerning;
@@ -446,19 +427,19 @@
}
GlyphInfo *
-TextFont::GetGlyphInfo (uint32_t unichar)
+TextFont::GetGlyphInfo (gunichar unichar)
{
GlyphInfo *glyph;
- uint32_t index;
+ uint32_t i;
- if (unichar == 0)
- return NULL;
+ i = unichar & 0xff;
+ glyph = &glyphs[i];
- index = unichar & 0xff;
- glyph = &glyphs[index];
-
if (glyph->unichar != unichar) {
- glyph->index = FcFreeTypeCharIndex (face, unichar);
+ if (unichar)
+ glyph->index = FcFreeTypeCharIndex (face, unichar);
+ else
+ glyph->index = 0;
glyph->unichar = unichar;
if (glyph->bitmap) {
@@ -480,7 +461,7 @@
glyph->path = NULL;
}
- if (glyph->index > 0 && FT_Load_Glyph (face, glyph->index,
LOAD_FLAGS) == 0) {
+ if (FT_Load_Glyph (face, glyph->index, LOAD_FLAGS) == 0) {
if (FT_Render_Glyph (face->glyph,
FT_RENDER_MODE_NORMAL) != 0)
goto unavail;
@@ -557,6 +538,26 @@
return NULL;
}
+GlyphInfo *
+TextFont::GetGlyphInfoByIndex (uint32_t index)
+{
+ gunichar unichar;
+ uint32_t idx;
+
+ if (index != 0) {
+ unichar = FT_Get_First_Char (face, &idx);
+ while (idx != index && idx != 0)
+ unichar = FT_Get_Next_Char (face, unichar, &idx);
+
+ if (idx == 0)
+ return NULL;
+ } else {
+ unichar = 0;
+ }
+
+ return GetGlyphInfo (unichar);
+}
+
double
TextFont::UnderlinePosition ()
{
@@ -611,7 +612,7 @@
}
void
-TextFont::Render (cairo_t *cr, uint32_t unichar, double x, double y)
+TextFont::Render (cairo_t *cr, gunichar unichar, double x, double y)
{
GlyphInfo *glyph;
@@ -636,7 +637,7 @@
}
void
-TextFont::Path (cairo_t *cr, uint32_t unichar, double x, double y)
+TextFont::Path (cairo_t *cr, gunichar unichar, double x, double y)
{
GlyphInfo *glyph;
@@ -703,6 +704,9 @@
FcDefaultSubstitute (pattern);
+ if ((set & FontMaskFilename))
+ return pattern;
+
if (!(matched = FcFontMatch (NULL, pattern, &result)))
return pattern;
@@ -1307,7 +1311,7 @@
{
TextSegment *segment;
bool clipped = false;
- uint32_t prev = 0;
+ gunichar prev = 0;
GlyphInfo *glyph;
TextLine *line;
double advance;
@@ -1512,8 +1516,8 @@
TextSegment *segment;
TextDecorations deco;
TextFont *font = NULL;
- const uint32_t *text;
- uint32_t prev = 0;
+ const gunichar *text;
+ gunichar prev = 0;
Brush *cur_fg = NULL;
Brush *fg = NULL;
GlyphInfo *glyph;
Modified: trunk/moon/src/font.h
===================================================================
--- trunk/moon/src/font.h 2007-10-03 17:35:36 UTC (rev 86823)
+++ trunk/moon/src/font.h 2007-10-03 17:40:44 UTC (rev 86824)
@@ -13,6 +13,7 @@
#include <stdint.h>
+#include <glib.h>
#include <cairo.h>
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -87,8 +88,27 @@
void font_init (void);
G_END_DECLS
-struct GlyphInfo;
+struct GlyphBitmap;
+struct GlyphMetrics {
+ double horiBearingX;
+ double horiBearingY;
+ double horiAdvance;
+ double vertBearingX;
+ double vertBearingY;
+ double vertAdvance;
+ double height;
+ double width;
+};
+
+struct GlyphInfo {
+ gunichar unichar;
+ uint32_t index;
+ GlyphMetrics metrics;
+ GlyphBitmap *bitmap;
+ moon_path *path;
+};
+
class TextFont {
int ref_count;
@@ -111,11 +131,12 @@
static TextFont *Load (FcPattern *pattern);
- GlyphInfo *GetGlyphInfo (uint32_t unichar);
+ GlyphInfo *GetGlyphInfo (gunichar unichar);
+ GlyphInfo *GetGlyphInfoByIndex (uint32_t index);
bool IsScalable ();
- double Kerning (uint32_t left, uint32_t right);
+ double Kerning (gunichar left, gunichar right);
double Descender ();
double Ascender ();
double Height ();
@@ -125,10 +146,10 @@
double UnderlineThickness ();
void Path (cairo_t *cr, GlyphInfo *glyph, double x, double y);
- void Path (cairo_t *cr, uint32_t unichar, double x, double y);
+ void Path (cairo_t *cr, gunichar unichar, double x, double y);
void Render (cairo_t *cr, GlyphInfo *glyph, double x, double y);
- void Render (cairo_t *cr, uint32_t unichar, double x, double y);
+ void Render (cairo_t *cr, gunichar unichar, double x, double y);
};
@@ -190,7 +211,7 @@
class TextRun : public List::Node {
public:
TextDecorations deco;
- uint32_t *text;
+ gunichar *text;
TextFont *font;
Brush **fg;
Modified: trunk/moon/src/mplayer.cpp
===================================================================
--- trunk/moon/src/mplayer.cpp 2007-10-03 17:35:36 UTC (rev 86823)
+++ trunk/moon/src/mplayer.cpp 2007-10-03 17:40:44 UTC (rev 86824)
@@ -390,7 +390,7 @@
current_pts = 0;
target_pts = 0;
seek_pts = 0;
-
+
height = 0;
width = 0;
}
Modified: trunk/moon/src/text.cpp
===================================================================
--- trunk/moon/src/text.cpp 2007-10-03 17:35:36 UTC (rev 86823)
+++ trunk/moon/src/text.cpp 2007-10-03 17:40:44 UTC (rev 86824)
@@ -15,11 +15,13 @@
#include <gtk/gtk.h>
#include <cairo.h>
+#include <stdlib.h>
#include <string.h>
#include "runtime.h"
#include "color.h"
#include "text.h"
+#include "uri.h"
extern guint32 moonlight_flags;
@@ -354,7 +356,7 @@
foreground = NULL;
- dirty_actual_values = true;
+ dirty = true;
actual_height = 0.0;
actual_width = 0.0;
bbox_height = 0.0;
@@ -583,7 +585,7 @@
text_block_set_actual_height (this, actual_height);
text_block_set_actual_width (this, actual_width);
- dirty_actual_values = false;
+ dirty = false;
}
void
@@ -743,9 +745,9 @@
text_block_set_actual_height (this, (double) h);
text_block_set_actual_width (this, (double) w);
- dirty_actual_values = false;
bbox_height = actual_height;
bbox_width = actual_width;
+ dirty = false;
}
void
@@ -777,7 +779,6 @@
void
TextBlock::OnPropertyChanged (DependencyProperty *prop)
{
- bool recalc_actual = true;
bool invalidate = true;
if (prop->type != Type::TEXTBLOCK) {
@@ -791,32 +792,43 @@
pango_font_description_set_family (font.pango, family);
else
font.custom->SetFamily (family);
+
+ dirty = true;
} else if (prop == TextBlock::FontSizeProperty) {
double size = text_block_get_font_size (this);
if (RENDER_USING_PANGO)
pango_font_description_set_absolute_size (font.pango,
size * PANGO_SCALE);
else
font.custom->SetSize (size);
+
+ dirty = true;
} else if (prop == TextBlock::FontStretchProperty) {
FontStretches stretch = text_block_get_font_stretch (this);
if (RENDER_USING_PANGO)
pango_font_description_set_stretch (font.pango,
font_stretch (stretch));
else
font.custom->SetStretch (stretch);
+
+ dirty = true;
} else if (prop == TextBlock::FontStyleProperty) {
FontStyles style = text_block_get_font_style (this);
if (RENDER_USING_PANGO)
pango_font_description_set_style (font.pango,
font_style (style));
else
font.custom->SetStyle (style);
+
+ dirty = true;
} else if (prop == TextBlock::FontWeightProperty) {
FontWeights weight = text_block_get_font_weight (this);
if (RENDER_USING_PANGO)
pango_font_description_set_weight (font.pango,
font_weight (weight));
else
font.custom->SetWeight (weight);
+
+ dirty = true;
} else if (prop == TextBlock::TextProperty) {
// handled elsewhere
+ dirty = true;
} else if (prop == TextBlock::InlinesProperty) {
Inlines *newcol = GetValue (prop)->AsInlines ();
@@ -825,6 +837,8 @@
printf ("Warning we attached a property that
was already attached\n");
newcol->closure = this;
}
+
+ dirty = true;
} else if (prop == TextBlock::ForegroundProperty) {
if (foreground != NULL) {
foreground->Detach (NULL, this);
@@ -835,22 +849,15 @@
foreground->Attach (NULL, this);
foreground->ref ();
}
-
- // Foreground property changes do not require a re-layout of
the text
- recalc_actual = false;
} else if (prop == TextBlock::ActualHeightProperty) {
- recalc_actual = false;
invalidate = false;
} else if (prop == TextBlock::ActualWidthProperty) {
- recalc_actual = false;
invalidate = false;
}
if (invalidate) {
- if (recalc_actual) {
- dirty_actual_values = true;
+ if (dirty)
UpdateBounds (true);
- }
Invalidate ();
}
@@ -871,7 +878,7 @@
TextBlock::OnCollectionChanged (Collection *col, CollectionChangeType type,
DependencyObject *obj, DependencyProperty *prop)
{
if (prop != Inline::ForegroundProperty) {
- dirty_actual_values = true;
+ dirty = true;
UpdateBounds (true);
}
@@ -881,7 +888,7 @@
Value *
TextBlock::GetValue (DependencyProperty *property)
{
- if (dirty_actual_values && ((property ==
TextBlock::ActualHeightProperty) || (property ==
TextBlock::ActualWidthProperty)))
+ if (dirty && ((property == TextBlock::ActualHeightProperty) ||
(property == TextBlock::ActualWidthProperty)))
CalcActualWidthHeight (NULL);
if (property == TextBlock::TextProperty) {
@@ -946,7 +953,7 @@
Run *run = new Run ();
if (value)
run_set_text (run, value->AsString ());
-
+
Inlines *inlines = text_block_get_inlines (this);
if (!inlines) {
@@ -959,6 +966,7 @@
inlines->Add (run);
run->unref ();
+ dirty = true;
return;
}
@@ -1148,17 +1156,303 @@
DependencyProperty *Glyphs::StyleSimulationsProperty;
DependencyProperty *Glyphs::UnicodeStringProperty;
+enum GlyphAttrMask {
+ Index = 1 << 1,
+ Advance = 1 << 2,
+ uOffset = 1 << 3,
+ vOffset = 1 << 4,
+};
+
+class GlyphAttr : public List::Node {
+public:
+ uint32_t index;
+ double advance;
+ double uoffset;
+ double voffset;
+ uint8_t set;
+
+ GlyphAttr ();
+};
+
+GlyphAttr::GlyphAttr ()
+{
+ set = 0;
+}
+
+Glyphs::Glyphs ()
+{
+ desc = new TextFontDescription ();
+ desc->SetSize (0.0);
+ downloader = NULL;
+ font = NULL;
+
+ fill = NULL;
+ path = NULL;
+
+ attrs = new List ();
+ text = NULL;
+
+ origin_y_specified = false;
+ origin_x = 0.0;
+ origin_y = 0.0;
+
+ height = 0.0;
+ width = 0.0;
+
+ invalid = false;
+ dirty = false;
+}
+
+Glyphs::~Glyphs ()
+{
+ if (fill)
+ fill->unref ();
+
+ if (font)
+ font->unref ();
+
+ if (path)
+ cairo_path_destroy (path);
+
+ if (downloader) {
+ downloader_abort (downloader);
+ downloader->unref ();
+ }
+
+ attrs->Clear (true);
+ delete attrs;
+
+ g_free (text);
+
+ delete desc;
+}
+
void
+Glyphs::Layout ()
+{
+ double x, y, w, h;
+ GlyphInfo *glyph;
+ GlyphAttr *attr;
+ int n = 0;
+
+ invalid = false;
+ dirty = false;
+
+ height = 0.0;
+ width = 0.0;
+
+ if (font) {
+ font->unref ();
+ font = NULL;
+ }
+
+ if (path) {
+ cairo_path_destroy (path);
+ path = NULL;
+ }
+
+ if (!desc->GetFilename () || desc->GetSize () == 0.0) {
+ // required font fields have not been set
+ return;
+ }
+
+ if (((!text || !text[0]) && attrs->IsEmpty ())) {
+ // no glyphs to render
+ return;
+ }
+
+ if (fill == NULL) {
+ // no fill specified (unlike TextBlock, there is no default
brush)
+ return;
+ }
+
+ font = desc->GetFont ();
+
+ x = origin_x;
+ if (!origin_y_specified)
+ y = font->Height ();
+ else
+ y = origin_y;
+
+ h = y - font->Descender ();
+ w = x;
+
+ attr = (GlyphAttr *) attrs->First ();
+
+ if (text && text[0]) {
+ gunichar *c = text;
+
+ while (*c != 0) {
+ if (attr && (attr->set & Index))
+ glyph = font->GetGlyphInfoByIndex (attr->index);
+ else
+ glyph = font->GetGlyphInfo (*c);
+
+ if (!glyph)
+ goto next1;
+
+ if (attr && (attr->set & vOffset))
+ h = MAX (y - attr->voffset, h);
+
+ if (attr && (attr->set & uOffset))
+ x += attr->uoffset;
+
+ w = MAX (x + glyph->metrics.horiAdvance, w);
+
+ if (attr && (attr->set & Advance))
+ x += attr->advance;
+ else
+ x += glyph->metrics.horiAdvance;
+
+ next1:
+
+ attr = attr ? (GlyphAttr *) attr->next : NULL;
+ n++;
+ c++;
+ }
+ }
+
+ while (attr) {
+ if (!(attr->set & Index)) {
+ fprintf (stderr, "No index specified for glyph %d\n", n
+ 1);
+ invalid = true;
+ return;
+ }
+
+ if (!(glyph = font->GetGlyphInfoByIndex (attr->index)))
+ goto next2;
+
+ if ((attr->set & vOffset))
+ h = MAX (y - attr->voffset, h);
+
+ if ((attr->set & uOffset))
+ x += attr->uoffset;
+
+ w = MAX (x + glyph->metrics.horiAdvance, w);
+
+ if ((attr->set & Advance))
+ x += attr->advance;
+ else
+ x += glyph->metrics.horiAdvance;
+
+ next2:
+
+ attr = (GlyphAttr *) attr->next;
+ n++;
+ }
+
+ height = h > 0.0 ? h : 0.0;
+ width = w;
+}
+
+void
Glyphs::Render (cairo_t *cr, int x, int y, int width, int height)
{
- // FIXME: implement me
+ GlyphInfo *glyph;
+ GlyphAttr *attr;
+ double x0, y0;
+ double y1;
+
+ if ((width == 0.0 && height == 0.0) || invalid)
+ return;
+
+ fill->SetupBrush (cr, this);
+
+ if (path) {
+ cairo_append_path (cr, path);
+ cairo_fill (cr);
+ return;
+ }
+
+ x0 = origin_x;
+ if (!origin_y_specified)
+ y0 = font->Height ();
+ else
+ y0 = origin_y;
+
+ attr = (GlyphAttr *) attrs->First ();
+
+ if (font->IsScalable ())
+ cairo_new_path (cr);
+
+ if (text && text[0]) {
+ gunichar *c = text;
+
+ while (*c != 0) {
+ if (attr && (attr->set & Index)) {
+ printf ("glyph index %lu was specified to use
in place of char %c\n", attr->index, (char) *c);
+ glyph = font->GetGlyphInfoByIndex (attr->index);
+ } else
+ glyph = font->GetGlyphInfo (*c);
+
+ if (!glyph)
+ goto next1;
+
+ if (attr && (attr->set & vOffset))
+ y1 = y0 - attr->voffset;
+ else
+ y1 = y0;
+
+ if (attr && (attr->set & uOffset))
+ x0 += attr->uoffset;
+
+ font->Path (cr, glyph, x0, y1);
+
+ if (attr && (attr->set & Advance))
+ x0 += attr->advance;
+ else
+ x0 += glyph->metrics.horiAdvance;
+
+ next1:
+
+ attr = attr ? (GlyphAttr *) attr->next : NULL;
+ c++;
+ }
+ }
+
+ while (attr) {
+ if (!(glyph = font->GetGlyphInfoByIndex (attr->index)))
+ goto next2;
+
+ if ((attr->set & vOffset))
+ y1 = y0 - attr->voffset;
+ else
+ y1 = y0;
+
+ if ((attr->set & uOffset))
+ x0 += attr->uoffset;
+
+ if (!font->IsScalable ())
+ font->Render (cr, glyph, x0, y1);
+ else
+ font->Path (cr, glyph, x0, y1);
+
+ if ((attr->set & Advance))
+ x0 += attr->advance;
+ else
+ x0 += glyph->metrics.horiAdvance;
+
+ next2:
+
+ attr = (GlyphAttr *) attr->next;
+ }
+
+ if (font->IsScalable ()) {
+ cairo_close_path (cr);
+
+ path = cairo_copy_path (cr);
+
+ cairo_fill (cr);
+ }
}
void
Glyphs::ComputeBounds ()
{
- // FIXME: implement me
- bounds = Rect (0, 0, 0, 0);
+ if (dirty)
+ Layout ();
+
+ bounds = bounding_rect_for_transformed_rect (&absolute_xform, Rect (0,
0, width, height));
}
Point
@@ -1171,48 +1465,238 @@
void
Glyphs::OnSubPropertyChanged (DependencyProperty *prop, DependencyProperty
*subprop)
{
- if (prop == Glyphs::FillProperty) {
- printf ("Glyphs::FillProperty subproperty changed\n");
- }
+ if (prop == Glyphs::FillProperty)
+ Invalidate ();
else
FrameworkElement::OnSubPropertyChanged (prop, subprop);
}
void
+Glyphs::data_write (guchar *buf, gsize offset, gsize count, gpointer data)
+{
+ ;
+}
+
+void
+Glyphs::size_notify (int64_t size, gpointer data)
+{
+ ;
+}
+
+void
+Glyphs::downloader_complete (EventObject *sender, gpointer calldata, gpointer
closure)
+{
+ ((Glyphs *) closure)->DownloaderComplete ();
+}
+
+void
+Glyphs::DownloaderComplete ()
+{
+ char *filename = downloader_get_response_file (downloader, "");
+ Value *value = downloader->GetValue (Downloader::UriProperty);
+ const char *str;
+ int id = 0;
+ Uri *uri;
+
+ /* the download was aborted */
+ if (!filename)
+ return;
+
+ if (value && (str = value->AsString ())) {
+ uri = new Uri ();
+
+ if (uri->Parse (str) && uri->fragment) {
+ if ((id = strtol (uri->fragment, NULL, 10)) < 0)
+ id = 0;
+ }
+
+ delete uri;
+ }
+
+ desc->SetFilename (filename);
+ desc->SetIndex (id);
+ g_free (filename);
+ dirty = true;
+
+ UpdateBounds (true);
+ Invalidate ();
+}
+
+void
+Glyphs::SetIndices (const char *in)
+{
+ register const char *inptr = in;
+ GlyphAttr *glyph;
+ double value;
+ char *end;
+ uint bit;
+ int n;
+
+ attrs->Clear (true);
+
+ if (in == NULL)
+ return;
+
+ while (g_ascii_isspace (*inptr))
+ inptr++;
+
+ while (*inptr) {
+ glyph = new GlyphAttr ();
+
+ while (g_ascii_isspace (*inptr))
+ inptr++;
+
+ glyph->index = strtoul (inptr, &end, 10);
+ if (end > inptr)
+ glyph->set |= Index;
+
+ inptr = end;
+ while (g_ascii_isspace (*inptr))
+ inptr++;
+
+ bit = (uint) Advance;
+ n = 0;
+
+ while (*inptr == ',' && n < 3) {
+ inptr++;
+ while (g_ascii_isspace (*inptr))
+ inptr++;
+
+ value = strtod (inptr, &end);
+
+ if (end > inptr) {
+ switch ((GlyphAttrMask) bit) {
+ case Advance:
+ glyph->advance = value / 4.0;
+ glyph->set |= Advance;
+ break;
+ case uOffset:
+ glyph->uoffset = value / 4.0;
+ glyph->set |= uOffset;
+ break;
+ case vOffset:
+ glyph->voffset = value / 4.0;
+ glyph->set |= vOffset;
+ break;
+ default:
+ break;
+ }
+ }
+
+ inptr = end;
+ while (g_ascii_isspace (*inptr))
+ inptr++;
+
+ bit <<= 1;
+ n++;
+ }
+
+ attrs->Append (glyph);
+
+ while (g_ascii_isspace (*inptr))
+ inptr++;
+
+ if (*inptr != ';') {
+ if (*inptr) {
+ int i;
+
+ fprintf (stderr, "Parse error: %s\n", in);
+ fprintf (stderr, " ");
+ for (i = 0; i < (inptr - in); i++)
+ fputc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ break;
+ }
+
+ inptr++;
+ }
+}
+
+void
Glyphs::OnPropertyChanged (DependencyProperty *prop)
{
+ bool invalidate = true;
+
if (prop->type != Type::GLYPHS) {
FrameworkElement::OnPropertyChanged (prop);
return;
}
- if (prop == Glyphs::FillProperty) {
- printf ("Glyphs::Fill property changed\n");
+ if (prop == Glyphs::FontUriProperty) {
+ char *uri = glyphs_get_font_uri (this);
+
+ if (downloader) {
+ downloader_abort (downloader);
+ downloader->unref ();
+ downloader = NULL;
+ }
+
+ if (uri && *uri) {
+ downloader = new Downloader ();
+
+ //printf ("setting media source to %s\n", uri);
+ downloader_open (downloader, "GET", uri);
+ downloader->AddHandler (downloader->CompletedEvent,
downloader_complete, this);
+ if (downloader->Started () || downloader->Completed ())
{
+ if (downloader->Completed ())
+ DownloaderComplete ();
+ } else {
+ downloader->SetWriteFunc (data_write,
size_notify, this);
+
+ // This is what actually triggers the download
+ downloader->Send ();
+ }
+ }
+
+ invalidate = false;
+ } else if (prop == Glyphs::FillProperty) {
+ if (fill != NULL) {
+ fill->Detach (NULL, this);
+ fill->unref ();
+ }
+
+ if ((fill = glyphs_get_fill (this)) != NULL) {
+ fill->Attach (NULL, this);
+ fill->ref ();
+ }
+ } else if (prop == Glyphs::UnicodeStringProperty) {
+ char *str = glyphs_get_unicode_string (this);
+ g_free (text);
+
+ if (str != NULL)
+ text = g_utf8_to_ucs4_fast (str, -1, NULL);
+ else
+ text = NULL;
+
+ dirty = true;
+ } else if (prop == Glyphs::IndicesProperty) {
+ char *str = glyphs_get_indices (this);
+ SetIndices (str);
+ dirty = true;
} else if (prop == Glyphs::FontRenderingEmSizeProperty) {
double size = glyphs_get_font_rendering_em_size (this);
- printf ("Glyphs::FontRenderingEmSize property changed to %g\n",
size);
- } else if (prop == Glyphs::FontUriProperty) {
- char *uri = glyphs_get_font_uri (this);
- printf ("Glyphs::FontUri property changed to %s\n", uri);
- } else if (prop == Glyphs::IndicesProperty) {
- char *indices = glyphs_get_indices (this);
- printf ("Glyphs::Indicies property changed to %s\n", indices);
+ desc->SetSize (size);
+ dirty = true;
} else if (prop == Glyphs::OriginXProperty) {
- double x = glyphs_get_origin_x (this);
- printf ("Glyphs::OriginX property changed to %g\n", x);
- } else if (prop == Glyphs::OriginXProperty) {
- double y = glyphs_get_origin_y (this);
- printf ("Glyphs::OriginY property changed to %g\n", y);
+ origin_x = glyphs_get_origin_x (this);
+ dirty = true;
+ } else if (prop == Glyphs::OriginYProperty) {
+ origin_y = glyphs_get_origin_y (this);
+ origin_y_specified = true;
+ dirty = true;
} else if (prop == Glyphs::StyleSimulationsProperty) {
- StyleSimulations sims = glyphs_get_style_simulations (this);
- printf ("Glyphs::StyleSimulations property changed to %d\n",
sims);
- } else if (prop == Glyphs::UnicodeStringProperty) {
- char *str = glyphs_get_unicode_string (this);
- printf ("Glyphs::UnicodeString property changed to %s\n", str);
+ // Silverlight 1.0 does not implement this property
+ invalidate = false;
}
- FullInvalidate (false);
-
+ if (invalidate)
+ Invalidate ();
+
+ if (dirty)
+ UpdateBounds (true);
+
NotifyAttacheesOfPropertyChange (prop);
}
Modified: trunk/moon/src/text.h
===================================================================
--- trunk/moon/src/text.h 2007-10-03 17:35:36 UTC (rev 86823)
+++ trunk/moon/src/text.h 2007-10-03 17:40:44 UTC (rev 86824)
@@ -16,6 +16,8 @@
#include <cairo.h>
#include <pango/pango.h>
+#include "downloader.h"
+#include "moon-path.h"
#include "brush.h"
#include "mango.h"
#include "font.h"
@@ -106,11 +108,11 @@
MangoRenderer *renderer;
Brush *foreground;
- bool dirty_actual_values;
double actual_height;
double actual_width;
double bbox_height;
double bbox_width;
+ bool dirty;
void CalcActualWidthHeight (cairo_t *cr);
void Layout (cairo_t *cr);
@@ -118,14 +120,14 @@
double GetBoundingWidth ()
{
- if (dirty_actual_values)
+ if (dirty)
CalcActualWidthHeight (NULL);
return bbox_width;
}
double GetBoundingHeight ()
{
- if (dirty_actual_values)
+ if (dirty)
CalcActualWidthHeight (NULL);
return bbox_height;
}
@@ -155,14 +157,14 @@
double GetActualWidth ()
{
- if (dirty_actual_values)
+ if (dirty)
CalcActualWidthHeight (NULL);
return actual_width;
}
double GetActualHeight ()
{
- if (dirty_actual_values)
+ if (dirty)
CalcActualWidthHeight (NULL);
return actual_height;
}
@@ -226,6 +228,33 @@
class Glyphs : public FrameworkElement {
+ TextFontDescription *desc;
+ Downloader *downloader;
+ TextFont *font;
+
+ cairo_path_t *path;
+ gunichar *text;
+ List *attrs;
+ Brush *fill;
+
+ bool origin_y_specified;
+ double origin_x;
+ double origin_y;
+ double height;
+ double width;
+
+ bool invalid;
+ bool dirty;
+
+ void Layout ();
+ void SetIndices (const char *in);
+
+ void DownloaderComplete ();
+
+ static void data_write (guchar *data, gsize n, gsize nn, void *closure);
+ static void downloader_complete (EventObject *sender, gpointer
calldata, gpointer closure);
+ static void size_notify (int64_t size, gpointer data);
+
public:
static DependencyProperty *FillProperty;
static DependencyProperty *FontRenderingEmSizeProperty;
@@ -236,7 +265,9 @@
static DependencyProperty *StyleSimulationsProperty;
static DependencyProperty *UnicodeStringProperty;
- Glyphs () { }
+ Glyphs ();
+ ~Glyphs ();
+
virtual Type::Kind GetObjectType () { return Type::GLYPHS; };
virtual void Render (cairo_t *cr, int x, int y, int width, int height);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches