Exemplo n.º 1
0
static PangoGlyph pango_font_get_glyph(PangoFont* font, PangoContext* context, gunichar wc)
{
    PangoGlyph result = 0;
    gchar buffer[7];

    gint  length = g_unichar_to_utf8(wc, buffer);
    g_return_val_if_fail(length, 0);

    GList* items = pango_itemize(context, buffer, 0, length, NULL, NULL);

    if (g_list_length(items) == 1) {
        PangoItem* item = reinterpret_cast<PangoItem*>(items->data);
        PangoFont* tmpFont = item->analysis.font;
        item->analysis.font = font;

        PangoGlyphString* glyphs = pango_glyph_string_new();
        pango_shape(buffer, length, &item->analysis, glyphs);

        item->analysis.font = tmpFont;

        if (glyphs->num_glyphs == 1)
            result = glyphs->glyphs[0].glyph;
        else
            g_warning("didn't get 1 glyph but %d", glyphs->num_glyphs);

        pango_glyph_string_free(glyphs);
    }

    g_list_foreach(items, (GFunc)pango_item_free, NULL);
    g_list_free(items);

    return result;
}
Exemplo n.º 2
0
static VALUE
rpango_shape_ensure(VALUE value)
{
    pango_glyph_string_free((PangoGlyphString *)value);

    return Qnil;
}
Exemplo n.º 3
0
/// Free upto a max of cGlyphs or upto first NULL.
void FreeGlyphs(WORD *pwGlyphs, int cGlyphs)
{
	PangoGlyphString ** glyphString = reinterpret_cast<PangoGlyphString**>(pwGlyphs);
	for(int i = 0 ; i < cGlyphs; ++i)
	{
		if (glyphString[i] == NULL)
			break;
		pango_glyph_string_free(glyphString[i]);
	}
}
Exemplo n.º 4
0
static VALUE
rpango_shape(VALUE self, VALUE text, VALUE analysis)
{
    VALUE ret;
    PangoGlyphString* glyphs = pango_glyph_string_new();
    StringValue(text);
    pango_shape(RSTRING_PTR(text), RSTRING_LEN(text), RVAL2BOXED(analysis, PANGO_TYPE_ANALYSIS), glyphs);
    ret = BOXED2RVAL(glyphs, PANGO_TYPE_GLYPH_STRING);
    pango_glyph_string_free (glyphs);
    return ret;
}
Exemplo n.º 5
0
void _HYPlatformGraphicPane::_ResetCharGlyphs(void)
{
    if (charCachePangoItems) {
        g_list_free (charCachePangoItems);
        charCachePangoItems = NULL;
    }
    for (long k=0; k<=60; k=k+1)
        if (cachedCharacterGlyphs[k]) {
            pango_glyph_string_free ((PangoGlyphString* )cachedCharacterGlyphs[k]);
            cachedCharacterGlyphs[k] = NULL;
        }
}
Exemplo n.º 6
0
GtkPaintContext::~GtkPaintContext() {
	if (myPixmap != 0) {
		gdk_pixmap_unref(myPixmap);
	}
	if (myTextGC) {
		gdk_gc_unref(myTextGC);
		gdk_gc_unref(myFillGC);
	}

	pango_glyph_string_free(myString);
	
	if (myFontDescription != 0) {
		pango_font_description_free(myFontDescription);
	}

	if (myContext != 0) {
		g_object_unref(myContext);
	}
}
Exemplo n.º 7
0
// Helper function used in the implementation of ScriptShape
HRESULT PangoCharsToGlyph(SCRIPT_CACHE *psc, const char * chars, int cInChars, int cMaxItems, PangoGlyphString **pGlpyhs, int * pcItems)
{
	ScriptCacheImplementation * cache = reinterpret_cast<ScriptCacheImplementation*>(*psc);
	PangoContext * pangoContext;
	cache->m_vwGraphics->GetTextStyleContext(reinterpret_cast<HDC*>(&pangoContext));

	PangoAttrList * attributes_list = pango_attr_list_new();
	GList * items = pango_itemize(pangoContext, chars, 0, cInChars, attributes_list, NULL);

	int length = g_list_length(items);

	int glyphsCount = 0;
	pGlpyhs[0] = NULL;
	for(int i = 0; i < length; ++i)
	{
		PangoItem* item = static_cast<PangoItem*>(g_list_nth_data(items, i));

		PangoGlyphString * ptrPangoGlyphString = pango_glyph_string_new();
		pango_shape(chars + item->offset, item->length, &item->analysis, ptrPangoGlyphString);
		glyphsCount += ptrPangoGlyphString->num_glyphs;

		if (glyphsCount > cMaxItems)
		{
			pango_glyph_string_free(ptrPangoGlyphString);
			FreeGlyphs(reinterpret_cast<WORD*>(pGlpyhs), cMaxItems);
			pango_item_free(item);
			pango_attr_list_unref(attributes_list);
			g_list_free(items);
			return E_OUTOFMEMORY;
		}

		pGlpyhs[i] = ptrPangoGlyphString;
		if (i < (cMaxItems - 1))
			pGlpyhs[i + 1] = NULL; // null term the list (used for deleting etc.)
		pango_item_free(item);
	}

	pango_attr_list_unref(attributes_list);
	g_list_free(items);

	*pcItems = glyphsCount;
	return S_OK;
}
Exemplo n.º 8
0
void FontSupport::drawText(const WFont& font, const WRectF& rect,
			   const WTransform& transform, Bitmap& bitmap,
			   WFlags<AlignmentFlag> flags,
			   const WString& text)
{
  PANGO_LOCK;

  enabledFontFormats = enabledFontFormats_;

  PangoMatrix matrix;
  matrix.xx = transform.m11();
  matrix.xy = transform.m21();
  matrix.yx = transform.m12();
  matrix.yy = transform.m22();
  matrix.x0 = transform.dx();
  matrix.y0 = transform.dy();

  std::string utf8 = text.toUTF8();

  std::vector<PangoGlyphString *> glyphs;
  int width;

  pango_context_set_matrix(context_, &matrix);

  /*
   * Oh my god, somebody explain me why we need to do this...
   */
  WFont f = font;
  f.setSize(font.sizeLength().toPixels()
	    / pango_matrix_get_font_scale_factor(&matrix));

  GList *items = layoutText(f, utf8, glyphs, width);
  pango_context_set_matrix(context_, nullptr);

  AlignmentFlag hAlign = flags & AlignHorizontalMask;

  /* FIXME handle bidi ! */

  double x;
  switch (hAlign) {
  case AlignmentFlag::Left:
    x = rect.left();
    break;
  case AlignmentFlag::Right:
    x = rect.right() - pangoUnitsToDouble(width);
    break;
  case AlignmentFlag::Center:
    x = rect.center().x() - pangoUnitsToDouble(width/2);
    break;
  default:
    x = 0;
  }

  AlignmentFlag vAlign = flags & AlignVerticalMask;

  PangoFont *pangoFont = matchFont(font).pangoFont();
  PangoFontMetrics *metrics = pango_font_get_metrics(pangoFont, nullptr);

  double ascent
    = pangoUnitsToDouble(pango_font_metrics_get_ascent(metrics));
  double descent 
    = pangoUnitsToDouble(pango_font_metrics_get_descent(metrics));

  pango_font_metrics_unref(metrics);

  double baseline = ascent;
  double height = ascent + descent;

  double y;
  switch (vAlign) {
  case AlignmentFlag::Top:
    y = rect.top() + baseline;
    break;
  case AlignmentFlag::Middle:
    y = rect.center().y() - height / 2 + baseline;
    break;
  case AlignmentFlag::Bottom:
    y = rect.bottom() - height + baseline;
    break;
  default:
    y = 0;
  }

  FT_Bitmap bmp;
  bmp.buffer = bitmap.buffer();
  bmp.width = bitmap.width();
  bmp.rows = bitmap.height();
  bmp.pitch = bitmap.pitch();
  bmp.pixel_mode = FT_PIXEL_MODE_GRAY;
  bmp.num_grays = 16; // ???

  GList *elem;
  unsigned i = 0;

  for (elem = items; elem; elem = elem->next) {
    PangoItem *item = (PangoItem *)elem->data;
    PangoAnalysis *analysis = &item->analysis;

    PangoGlyphString *gl = glyphs[i++];

    pango_ft2_render_transformed(&bmp, &matrix,
				 analysis->font, gl,
				 pangoUnitsFromDouble(x),
				 pangoUnitsFromDouble(y));

    x += pangoUnitsToDouble(pango_glyph_string_get_width(gl));

    pango_glyph_string_free(gl);
    pango_item_free(item);
  }

  g_list_free(items);
}
Exemplo n.º 9
0
WTextItem FontSupport::measureText(const WFont& font, const WString& text,
				   double maxWidth, bool wordWrap)
{
  PANGO_LOCK;

  enabledFontFormats = enabledFontFormats_;

  /*
   * Note: accurate measuring on a bitmap requires that the transformation
   * is applied, because hinting may push chars to boundaries e.g. when
   * rotated (or scaled too?)
   */
  std::string utf8 = text.toUTF8();
  const char *s = utf8.c_str();

  if (wordWrap) {
    int utflen = g_utf8_strlen(s, -1);
    PangoLogAttr *attrs = new PangoLogAttr[utflen + 1];
    PangoLanguage *language = pango_language_from_string("en-US");

    pango_get_log_attrs(s, utf8.length(), -1, language, attrs, utflen + 1);

    double w = 0, nextW = -1;

    int current = 0;
    int measured = 0;
    int end = 0;

    bool maxWidthReached = false;

    for (int i = 0; i < utflen + 1; ++i) {
      if (i == utflen || attrs[i].is_line_break) {
	int cend = g_utf8_offset_to_pointer(s, end) - s;

	WTextItem ti
	  = measureText(font, WString::fromUTF8(utf8.substr(measured,
							    cend - measured)),
			-1, false);

	if (isEpsilonMore(w + ti.width(), maxWidth)) {
	  nextW = ti.width();
	  maxWidthReached = true;
	  break;
	} else {
	  measured = cend;
	  current = g_utf8_offset_to_pointer(s, i) - s;
	  w += ti.width();

	  if (i == utflen) {
	    w += measureText(font, WString::fromUTF8(utf8.substr(measured)),
			     -1, false).width();
	    measured = utf8.length();
	  }
	}
      }

      if (!attrs[i].is_white)
	end = i + 1;
    }

    delete[] attrs;

    if (maxWidthReached) {
      return WTextItem(WString::fromUTF8(utf8.substr(0, current)), w, nextW);
    } else {
      /*
       * For some reason, the sum of the individual widths is a bit less
       * (for longer stretches of text), so we re-measure it !
       */
      w = measureText(font, WString::fromUTF8(utf8.substr(0, measured)),
		      -1, false).width();
      return WTextItem(text, w);
    }
  } else {
    std::vector<PangoGlyphString *> glyphs;
    int width;

    GList *items = layoutText(font, utf8, glyphs, width);

    double w = pangoUnitsToDouble(width);

    for (unsigned i = 0; i < glyphs.size(); ++i)
      pango_glyph_string_free(glyphs[i]);

    g_list_foreach(items, (GFunc) pango_item_free, nullptr);
    g_list_free(items);

    return WTextItem(text, w);
  }
}
Exemplo n.º 10
0
void FontSupport::drawText(const WFont& font, const WRectF& rect,
			   WFlags<AlignmentFlag> flags, const WString& text)
{
  PANGO_LOCK;

  enabledFontFormats = enabledFontFormats_;

  std::string utf8 = text.toUTF8();

  std::vector<PangoGlyphString *> glyphs;
  int width;

  GList *items = layoutText(font, utf8, glyphs, width);

  AlignmentFlag hAlign = flags & AlignHorizontalMask;
  AlignmentFlag vAlign = flags & AlignVerticalMask;

  /* FIXME handle bidi ! */

  double x;
  switch (hAlign) {
  case AlignmentFlag::Left:
    x = rect.left();
    break;
  case AlignmentFlag::Right:
    x = rect.right() - pangoUnitsToDouble(width);
    break;
  case AlignmentFlag::Center:
    x = rect.center().x() - pangoUnitsToDouble(width/2);
    break;
  default:
    x = 0;
  }

  unsigned i = 0;
  for (GList *elem = items; elem; elem = elem->next) {
    PangoItem *item = (PangoItem *)elem->data;
    PangoAnalysis *analysis = &item->analysis;

    PangoGlyphString *gl = glyphs[i++];

    currentFont_ = analysis->font;

    /*
     * Note, we are actually ignoring the selected glyphs here, which
     * is a pitty and possibly wrong if the device does not make the
     * same selection !
     */
    WString s = WString::fromUTF8(utf8.substr(item->offset,
                                              item->length));

    device_->drawText(WRectF(x, rect.y(),
			     1000, rect.height()),
		      AlignmentFlag::Left | vAlign, TextFlag::SingleLine,
		      s, nullptr);

    WTextItem textItem = device_->measureText(s, -1, false);

    x += textItem.width();

    pango_item_free(item);
    pango_glyph_string_free(gl);
  }

  g_list_free(items);

  currentFont_ = nullptr;
}
JNIEXPORT jobject JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
  (JNIEnv *env, jobject self, 
   jstring chars,
   jobject font, 
   jobject fontRenderContext)
{
  struct peerfont *pfont = NULL;
  GList *items = NULL, *i = NULL;
  gchar *str = NULL;
  int len, j;
  double *native_extents;
  int *native_codes;
  jintArray java_codes = NULL;
  jdoubleArray java_extents = NULL;

  gdk_threads_enter ();

  pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
  g_assert (pfont != NULL);

  len = (*gdk_env())->GetStringUTFLength (env, chars);  
  str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
  g_assert (str != NULL);

  if (attrs == NULL)
    attrs = pango_attr_list_new ();

  if (len > 0 && str[len-1] == '\0')
    len--;
  
  items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL);

  i = g_list_first (items);

  if (i == NULL)       
    {
      java_extents = (*env)->NewDoubleArray (env, 0);
      java_codes = (*env)->NewIntArray (env, 0);
    }
  else
    { 
      PangoGlyphString *glyphs;
      PangoItem *item = (PangoItem *)i->data;

      pango_context_set_font_description (pfont->ctx, pfont->desc);
      pango_context_set_language (pfont->ctx, gtk_get_default_language());
      pango_context_load_font (pfont->ctx, pfont->desc);

      glyphs = pango_glyph_string_new ();
      g_assert (glyphs != NULL);

      pango_shape (str + item->offset, item->length, 
		   &(item->analysis), glyphs);

      if (glyphs->num_glyphs > 0)
	{
	  int x = 0;
	  double scale = ((double) PANGO_SCALE);

	  java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
	  java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
	  native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL);
	  native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);

	  for (j = 0; j < glyphs->num_glyphs; ++j)
	    {
	      PangoRectangle ink;
	      PangoRectangle logical;
	      PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry;

	      pango_font_get_glyph_extents (pfont->font, 
					    glyphs->glyphs[j].glyph,
					    &ink, &logical);

	      native_codes[j] = glyphs->glyphs[j].glyph;

	      native_extents[ GLYPH_LOG_X(j)      ] = (logical.x)      / scale;
	      native_extents[ GLYPH_LOG_Y(j)      ] = (- logical.y)    / scale;
	      native_extents[ GLYPH_LOG_WIDTH(j)  ] = (logical.width)  / scale;
	      native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale;

	      native_extents[ GLYPH_INK_X(j)      ] = (ink.x)       / scale;
	      native_extents[ GLYPH_INK_Y(j)      ] = (- ink.y)     / scale;
	      native_extents[ GLYPH_INK_WIDTH(j)  ] = (ink.width)   / scale;
	      native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height)  / scale;

	      native_extents[ GLYPH_POS_X(j)      ] = (x + geom->x_offset)  / scale;
	      native_extents[ GLYPH_POS_Y(j)      ] = (  - geom->y_offset)  / scale;

	      x += geom->width;
	    }
	  (*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0);
	  (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
	}

      pango_glyph_string_free (glyphs);
    }

  (*env)->ReleaseStringUTFChars (env, chars, str);
  
  for (i = g_list_first (items); i != NULL; i = g_list_next (i))
    g_free (i->data);
  
  g_list_free (items);

  gdk_threads_leave ();

  return (*env)->NewObject (env, 
			    glyphVector_class, 
			    glyphVector_ctor, 
			    java_extents, java_codes,
			    font, fontRenderContext);
}