Beispiel #1
0
CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const CFX_WideString& wsFaceName,
                                      int32_t iFaceIndex,
                                      int32_t* pFaceCount) {
  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
  if (!pFontMapper)
    return nullptr;

  IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
  if (!pSystemFontInfo)
    return nullptr;

  IFX_SeekableReadStream* pFontStream =
      CreateFontStream(wsFaceName.UTF8Encode());
  if (!pFontStream)
    return nullptr;

  std::unique_ptr<CFX_Font> pInternalFont(new CFX_Font());
  if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
    pFontStream->Release();
    return nullptr;
  }

  CFGAS_GEFont* pFont = CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
  if (!pFont) {
    pFontStream->Release();
    return nullptr;
  }

  m_IFXFont2FileRead.SetAt(pFont, pFontStream);
  if (pFaceCount)
    *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces;

  return pFont;
}
Beispiel #2
0
CFGAS_GEFont* CFGAS_FontMgr::LoadFont(CFGAS_GEFont* pSrcFont,
                                      uint32_t dwFontStyles,
                                      uint16_t wCodePage) {
  ASSERT(pSrcFont);
  if (pSrcFont->GetFontStyles() == dwFontStyles)
    return pSrcFont->Retain();
  void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles,
                     (void*)(uintptr_t)wCodePage};
  uint32_t dwHash = FX_HashCode_GetA(
      CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false);
  CFGAS_GEFont* pFont = nullptr;
  if (m_DeriveFonts.GetCount() > 0) {
    m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont);
    if (pFont)
      return pFont->Retain();
  }
  pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
  if (!pFont)
    return nullptr;

  m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
  int32_t index = m_Fonts.Find(pFont);
  if (index < 0) {
    m_Fonts.Add(pFont);
    pFont->Retain();
  }
  return pFont;
}
FX_BOOL CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode,
                                          CFX_Rect& bbox,
                                          FX_BOOL bRecursive,
                                          FX_BOOL bCharCode) {
  ASSERT(m_pRectArray);
  ASSERT(m_pBBoxMap);
  void* pRect = nullptr;
  if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
    CFGAS_GEFont* pFont = nullptr;
    int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
    if (iGlyph != 0xFFFF && pFont) {
      if (pFont == this) {
        FX_RECT rtBBox;
        if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
          CFX_Rect rt;
          rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
          int32_t index = m_pRectArray->Add(rt);
          pRect = m_pRectArray->GetPtrAt(index);
          m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect);
        }
      } else if (pFont->GetCharBBoxInternal(wUnicode, bbox, FALSE, bCharCode)) {
        return TRUE;
      }
    }
  }
  if (!pRect)
    return FALSE;

  bbox = *static_cast<const CFX_Rect*>(pRect);
  return TRUE;
}
FX_BOOL CFGAS_GEFont::GetCharWidthInternal(FX_WCHAR wUnicode,
                                           int32_t& iWidth,
                                           FX_BOOL bRecursive,
                                           FX_BOOL bCharCode) {
  ASSERT(m_pCharWidthMap);
  iWidth = m_pCharWidthMap->GetAt(wUnicode, 0);
  if (iWidth < 1) {
    if (!m_pProvider ||
        !m_pProvider->GetCharWidth(this, wUnicode, iWidth, bCharCode)) {
      CFGAS_GEFont* pFont = nullptr;
      int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
      if (iGlyph != 0xFFFF && pFont) {
        if (pFont == this) {
          iWidth = m_pFont->GetGlyphWidth(iGlyph);
          if (iWidth < 0) {
            iWidth = -1;
          }
        } else if (pFont->GetCharWidthInternal(wUnicode, iWidth, FALSE,
                                               bCharCode)) {
          return TRUE;
        }
      } else {
        iWidth = -1;
      }
    }
    m_pCharWidthMap->SetAtGrow(wUnicode, (int16_t)iWidth);
  } else if (iWidth == 65535) {
    iWidth = -1;
  }
  return iWidth > 0;
}
// static
CFGAS_GEFont* CFGAS_GEFont::LoadFont(CFX_Font* pExtFont,
                                     IFGAS_FontMgr* pFontMgr) {
  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
  if (!pFont->LoadFontInternal(pExtFont)) {
    pFont->Release();
    return nullptr;
  }
  return pFont;
}
// static
CFGAS_GEFont* CFGAS_GEFont::LoadFont(IFX_Stream* pFontStream,
                                     IFGAS_FontMgr* pFontMgr,
                                     FX_BOOL bSaveStream) {
  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
  if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) {
    pFont->Release();
    return nullptr;
  }
  return pFont;
}
// static
CFGAS_GEFont* CFGAS_GEFont::LoadFont(const uint8_t* pBuffer,
                                     int32_t iLength,
                                     IFGAS_FontMgr* pFontMgr) {
  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
  if (!pFont->LoadFontInternal(pBuffer, iLength)) {
    pFont->Release();
    return nullptr;
  }
  return pFont;
}
Beispiel #8
0
CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode,
                                              uint32_t dwFontStyles,
                                              const FX_WCHAR* pszFontFamily) {
  CFGAS_GEFont* pFont = nullptr;
  if (m_FailedUnicodes2Nullptr.Lookup(wUnicode, pFont))
    return nullptr;
  const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode);
  uint16_t wCodePage = x ? x->wCodePage : 0xFFFF;
  uint16_t wBitField = x ? x->wBitField : 0x03E7;
  CFX_ByteString bsHash;
  if (wCodePage == 0xFFFF)
    bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
  else
    bsHash.Format("%d, %d", wCodePage, dwFontStyles);
  bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
  uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
  CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr;
  if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
    if (!pFonts)
      return nullptr;

    for (int32_t i = 0; i < pFonts->GetSize(); ++i) {
      if (VerifyUnicode(pFonts->GetAt(i), wUnicode))
        return pFonts->GetAt(i)->Retain();
    }
  }
  if (!pFonts)
    pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>;
  m_Hash2Fonts.SetAt(dwHash, pFonts);
  CFX_FontDescriptorInfos* sortedFonts = nullptr;
  if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
    sortedFonts = new CFX_FontDescriptorInfos;
    MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
               CFX_WideString(pszFontFamily), wUnicode);
    m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
  }
  for (int32_t i = 0; i < sortedFonts->GetSize(); ++i) {
    CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont;
    if (!VerifyUnicode(pDesc, wUnicode))
      continue;
    pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
    if (!pFont)
      continue;
    pFont->SetLogicalFontStyle(dwFontStyles);
    pFonts->Add(pFont);
    return pFont;
  }
  if (!pszFontFamily)
    m_FailedUnicodes2Nullptr.SetAt(wUnicode, nullptr);
  return nullptr;
}
CFGAS_GEFont* CFGAS_StdFontMgrImp::LoadFont(const uint8_t* pBuffer,
                                            int32_t iLength) {
  ASSERT(pBuffer && iLength > 0);
  CFGAS_GEFont* pFont = nullptr;
  if (m_BufferFonts.Lookup((void*)pBuffer, (void*&)pFont)) {
    if (pFont) {
      return pFont->Retain();
    }
  }
  pFont = CFGAS_GEFont::LoadFont(pBuffer, iLength, this);
  if (pFont) {
    m_Fonts.Add(pFont);
    m_BufferFonts.SetAt((void*)pBuffer, pFont);
    return pFont->Retain();
  }
  return nullptr;
}
// static
CFGAS_GEFont* CFGAS_GEFont::LoadFont(const FX_WCHAR* pszFontFamily,
                                     uint32_t dwFontStyles,
                                     uint16_t wCodePage,
                                     IFGAS_FontMgr* pFontMgr) {
#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
  if (pFontMgr) {
    return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
  }
  return nullptr;
#else
  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
  if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) {
    pFont->Release();
    return nullptr;
  }
  return pFont;
#endif
}
CFGAS_GEFont* CFGAS_FontMgrImp::GetFontByCodePage(
    uint16_t wCodePage,
    uint32_t dwFontStyles,
    const FX_WCHAR* pszFontFamily) {
  CFX_ByteString bsHash;
  bsHash.Format("%d, %d", wCodePage, dwFontStyles);
  bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
  uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
  CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr;
  if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
    if (!pFonts)
      return nullptr;

    if (pFonts->GetSize() != 0)
      return pFonts->GetAt(0)->Retain();
  }

  if (!pFonts)
    pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>;

  m_Hash2Fonts.SetAt(dwHash, pFonts);
  CFX_FontDescriptorInfos* sortedFonts = nullptr;
  if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
    sortedFonts = new CFX_FontDescriptorInfos;
    MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
               CFX_WideString(pszFontFamily), 0);
    m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
  }
  if (sortedFonts->GetSize() == 0)
    return nullptr;

  CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont;
  CFGAS_GEFont* pFont =
      LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
  if (pFont)
    pFont->SetLogicalFontStyle(dwFontStyles);

  pFonts->Add(pFont);
  return pFont;
}
int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode,
                                    FX_BOOL bRecursive,
                                    CFGAS_GEFont** ppFont,
                                    FX_BOOL bCharCode) {
  ASSERT(m_pFontEncoding);
  int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode);
  if (iGlyphIndex > 0) {
    if (ppFont) {
      *ppFont = this;
    }
    return iGlyphIndex;
  }
  const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode);
  if (!pFontUSB) {
    return 0xFFFF;
  }
  uint16_t wBitField = pFontUSB->wBitField;
  if (wBitField >= 128) {
    return 0xFFFF;
  }
  auto it = m_FontMapper.find(wUnicode);
  CFGAS_GEFont* pFont = it != m_FontMapper.end() ? it->second : nullptr;
  if (pFont && pFont != this) {
    iGlyphIndex = pFont->GetGlyphIndex(wUnicode, FALSE, nullptr, bCharCode);
    if (iGlyphIndex != 0xFFFF) {
      int32_t i = m_SubstFonts.Find(pFont);
      if (i > -1) {
        iGlyphIndex |= ((i + 1) << 24);
        if (ppFont)
          *ppFont = pFont;
        return iGlyphIndex;
      }
    }
  }
  if (m_pFontMgr && bRecursive) {
    CFX_WideString wsFamily;
    GetFamilyName(wsFamily);
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    CFGAS_GEFont* pFont = m_pFontMgr->GetDefFontByUnicode(
        wUnicode, GetFontStyles(), wsFamily.c_str());
#else
    CFGAS_GEFont* pFont = m_pFontMgr->GetFontByUnicode(
        wUnicode, GetFontStyles(), wsFamily.c_str());
    if (!pFont)
      pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), nullptr);
#endif
    if (pFont) {
      if (pFont == this) {
        pFont->Release();
        return 0xFFFF;
      }
      m_FontMapper[wUnicode] = pFont;
      int32_t i = m_SubstFonts.GetSize();
      m_SubstFonts.Add(pFont);
      iGlyphIndex = pFont->GetGlyphIndex(wUnicode, FALSE, nullptr, bCharCode);
      if (iGlyphIndex != 0xFFFF) {
        iGlyphIndex |= ((i + 1) << 24);
        if (ppFont)
          *ppFont = pFont;
        return iGlyphIndex;
      }
    }
  }
  return 0xFFFF;
}