Exemplo n.º 1
0
/* static */
int FontUtils::FontScore(const unordered_map<char32, inT64>& ch_map,
                         const string& fontname,
                         int* raw_score,
                         vector<bool>* ch_flags) {
  PangoFontInfo font_info;
  if (!font_info.ParseFontDescriptionName(fontname)) {
    tprintf("ERROR: Could not parse %s\n", fontname.c_str());
  }
  PangoFont* font = font_info.ToPangoFont();
  PangoCoverage* coverage = pango_font_get_coverage(font, NULL);

  if (ch_flags) {
    ch_flags->clear();
    ch_flags->reserve(ch_map.size());
  }
  *raw_score = 0;
  int ok_chars = 0;
  for (unordered_map<char32, inT64>::const_iterator it = ch_map.begin();
       it != ch_map.end(); ++it) {
    bool covered = (IsWhitespace(it->first) ||
                    (pango_coverage_get(coverage, it->first)
                     == PANGO_COVERAGE_EXACT));
    if (covered) {
      ++(*raw_score);
      ok_chars += it->second;
    }
    if (ch_flags) {
      ch_flags->push_back(covered);
    }
  }
  return ok_chars;
}
Exemplo n.º 2
0
/* static */
void FontUtils::GetAllRenderableCharacters(const string& font_name,
                                           vector<bool>* unichar_bitmap) {
  PangoFontInfo font_info(font_name);
  PangoCoverage* coverage = pango_font_get_coverage(
      font_info.ToPangoFont(), NULL);
  CharCoverageMapToBitmap(coverage, unichar_bitmap);
}
Exemplo n.º 3
0
int PangoFontInfo::DropUncoveredChars(string* utf8_text) const {
  PangoFont* font = ToPangoFont();
  PangoCoverage* coverage = pango_font_get_coverage(font, NULL);
  int num_dropped_chars = 0;
  // Maintain two iterators that point into the string. For space efficiency, we
  // will repeatedly copy one covered UTF8 character from one to the other, and
  // at the end resize the string to the right length.
  char* out = const_cast<char*>(utf8_text->c_str());
  const UNICHAR::const_iterator it_begin =
      UNICHAR::begin(utf8_text->c_str(), utf8_text->length());
  const UNICHAR::const_iterator it_end =
      UNICHAR::end(utf8_text->c_str(), utf8_text->length());
  for (UNICHAR::const_iterator it = it_begin; it != it_end; ++it) {
    // Skip bad utf-8.
    if (!it.is_legal())
      continue;  // One suitable error message will still be issued.
    if (!IsWhitespace(*it) && !pango_is_zero_width(*it) &&
        pango_coverage_get(coverage, *it) != PANGO_COVERAGE_EXACT) {
      if (TLOG_IS_ON(2)) {
        char tmp[5];
        int len = it.get_utf8(tmp);
        tmp[len] = '\0';
        tlog(2, "'%s' (U+%x) not covered by font\n", tmp, *it);
      }
      ++num_dropped_chars;
      continue;
    }
    strncpy(out, it.utf8_data(), it.utf8_len());
    out += it.utf8_len();
  }
  utf8_text->resize(out - utf8_text->c_str());
  return num_dropped_chars;
}
Exemplo n.º 4
0
static VALUE
rg_get_coverage(VALUE self, VALUE language)
{
    PangoCoverage* c = pango_font_get_coverage(_SELF(self),
                       RVAL2PANGOLANGUAGE(language));
    return PANGOCOVERAGE2RVAL(c);
}
Exemplo n.º 5
0
static PangoCoverageLevel
pango_engine_shape_real_covers (PangoEngineShape *engine,
				PangoFont        *font,
				PangoLanguage    *language,
				gunichar          wc)
{

  PangoCoverage *coverage = pango_font_get_coverage (font, language);
  PangoCoverageLevel result = pango_coverage_get (coverage, wc);

  pango_coverage_unref (coverage);

  return result;
}
Exemplo n.º 6
0
/* static */
void FontUtils::GetAllRenderableCharacters(const vector<string>& fonts,
                                           vector<bool>* unichar_bitmap) {
  // Form the union of coverage maps from the fonts
  PangoCoverage* all_coverage = pango_coverage_new();
  tlog(1, "Processing %d fonts\n", fonts.size());
  for (int i = 0; i < fonts.size(); ++i) {
    PangoFontInfo font_info(fonts[i]);
    PangoCoverage* coverage = pango_font_get_coverage(
        font_info.ToPangoFont(), NULL);
    // Mark off characters that any font can render.
    pango_coverage_max(all_coverage, coverage);
  }
  CharCoverageMapToBitmap(all_coverage, unichar_bitmap);
  pango_coverage_unref(all_coverage);
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
    bool result = true;

    PangoCoverage* coverage = pango_font_get_coverage(m_platformData.m_font, pango_language_get_default());

    for (int i = 0; i < length; i++) {
        if (PANGO_COVERAGE_NONE == pango_coverage_get(coverage, characters[i])) {
            result = false;
            break;
        }
    }

    pango_coverage_unref(coverage);

    return result;
}
Exemplo n.º 8
0
bool PangoFontInfo::CoversUTF8Text(const char* utf8_text, int byte_length) const {
  PangoFont* font = ToPangoFont();
  PangoCoverage* coverage = pango_font_get_coverage(font, NULL);
  for (UNICHAR::const_iterator it = UNICHAR::begin(utf8_text, byte_length);
       it != UNICHAR::end(utf8_text, byte_length);
       ++it) {
    if (IsWhitespace(*it) || pango_is_zero_width(*it))
      continue;
    if (pango_coverage_get(coverage, *it) != PANGO_COVERAGE_EXACT) {
      char tmp[5];
      int len = it.get_utf8(tmp);
      tmp[len] = '\0';
      tlog(2, "'%s' (U+%x) not covered by font\n", tmp, *it);
      return false;
    }
  }
  return true;
}
Exemplo n.º 9
0
{
}

static void
pango_engine_lang_class_init (PangoEngineLangClass *klass)
{
}


static PangoCoverageLevel
pango_engine_shape_real_covers (PangoEngineShape *engine G_GNUC_UNUSED,
				PangoFont        *font,
				PangoLanguage    *language,
				gunichar          wc)
{
  PangoCoverage *coverage = pango_font_get_coverage (font, language);
  PangoCoverageLevel result = pango_coverage_get (coverage, wc);

  pango_coverage_unref (coverage);

  return result;
}

G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_DEFINE_ABSTRACT_TYPE (PangoEngineShape, pango_engine_shape, PANGO_TYPE_ENGINE);
G_GNUC_END_IGNORE_DEPRECATIONS

static void
pango_engine_shape_init (PangoEngineShape *klass)
{
}
Exemplo n.º 10
0
static void
basic_engine_shape (PangoEngineShape    *engine,
		    PangoFont           *font,
		    const char          *text,
		    gint                 length,
		    const PangoAnalysis *analysis,
		    PangoGlyphString    *glyphs)
{
  const char *p;
  char *copy;
  CTLineRef line;
  CFStringRef cstr;
  CFDictionaryRef attributes;
  CFAttributedStringRef attstr;
  PangoCoreTextFont *cfont = PANGO_CORE_TEXT_FONT (font);
  PangoCoverage *coverage;
  CFArrayRef runs;
  CTRunRef run;
  CTRunStatus run_status;
  CFIndex i, glyph_count;
  const CGGlyph *cgglyphs;

  CFTypeRef keys[] = {
      (CFTypeRef) kCTFontAttributeName
  };

  CFTypeRef values[] = {
      pango_core_text_font_get_ctfont (cfont)
  };

  attributes = CFDictionaryCreate (kCFAllocatorDefault,
                                   (const void **)keys,
                                   (const void **)values,
                                   1,
                                   &kCFCopyStringDictionaryKeyCallBacks,
                                   &kCFTypeDictionaryValueCallBacks);

  copy = g_strndup (text, length + 1);
  copy[length] = 0;

  cstr = CFStringCreateWithCString (kCFAllocatorDefault, copy,
                                    kCFStringEncodingUTF8);
  g_free (copy);

  attstr = CFAttributedStringCreate (kCFAllocatorDefault,
                                     cstr,
                                     attributes);

  line = CTLineCreateWithAttributedString (attstr);

  runs = CTLineGetGlyphRuns (line);

  /* Since Pango divides things into runs already, we assume there is
   * only a single run in this line.
   */
  run = CFArrayGetValueAtIndex (runs, 0);
  run_status = CTRunGetStatus (run);
  glyph_count = CTRunGetGlyphCount (run);
  cgglyphs = CTRunGetGlyphsPtr (run);

  p = text;
  pango_glyph_string_set_size (glyphs, glyph_count);
  coverage = pango_font_get_coverage (PANGO_FONT (cfont),
                                      analysis->language);

  for (i = 0; i < glyph_count; i++)
    {
      CFIndex real_i, prev_i;
      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 (run_status & kCTRunStatusRightToLeft)
        {
          real_i = glyph_count - i - 1;
          prev_i = real_i + 1;
        }
      else
        {
          real_i = i;
          prev_i = real_i - 1;
        }

      if (wc == 0xa0)	/* non-break-space */
	wc = 0x20;

      if (pango_is_zero_width (wc))
	{
	  set_glyph (font, glyphs, real_i, p - text, PANGO_GLYPH_EMPTY);
	}
      else
	{
          PangoCoverageLevel result;

          result = pango_coverage_get (coverage, wc);

          if (result != PANGO_COVERAGE_NONE)
            {
              set_glyph (font, glyphs, real_i, p - text, cgglyphs[real_i]);

              if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
                {
                  if (i > 0)
                    {
                      PangoRectangle logical_rect, ink_rect;

                      glyphs->glyphs[real_i].geometry.width = MAX (glyphs->glyphs[prev_i].geometry.width,
                                                                   glyphs->glyphs[prev_i].geometry.width);
                      glyphs->glyphs[prev_i].geometry.width = 0;
                      glyphs->log_clusters[real_i] = glyphs->log_clusters[prev_i];

                      /* Some heuristics to try to guess how overstrike glyphs are
                       * done and compensate
                       */
                      pango_font_get_glyph_extents (font, glyphs->glyphs[real_i].glyph, &ink_rect, &logical_rect);
                      if (logical_rect.width == 0 && ink_rect.x == 0)
                        glyphs->glyphs[real_i].geometry.x_offset = (glyphs->glyphs[real_i].geometry.width - ink_rect.width) / 2;
                    }
                }
            }
          else
            {
              set_glyph (font, glyphs, real_i, p - text,
                         PANGO_GET_UNKNOWN_GLYPH (wc));
            }
        }

      p = g_utf8_next_char (p);
    }

  CFRelease (line);
  CFRelease (attstr);
  CFRelease (cstr);
  CFRelease (attributes);
  pango_coverage_unref (coverage);
}