зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1740530 - patch 1 - Move COLR font support functions from gfxUtils into their own class. r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D152036
This commit is contained in:
Родитель
f3616b887b
Коммит
81c6e793b9
|
@ -0,0 +1,234 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "COLRFonts.h"
|
||||
#include "gfxFontUtils.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "harfbuzz/hb.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct COLRHeader {
|
||||
AutoSwap_PRUint16 version;
|
||||
AutoSwap_PRUint16 numBaseGlyphRecord;
|
||||
AutoSwap_PRUint32 offsetBaseGlyphRecord;
|
||||
AutoSwap_PRUint32 offsetLayerRecord;
|
||||
AutoSwap_PRUint16 numLayerRecords;
|
||||
};
|
||||
|
||||
struct COLRBaseGlyphRecord {
|
||||
AutoSwap_PRUint16 glyphId;
|
||||
AutoSwap_PRUint16 firstLayerIndex;
|
||||
AutoSwap_PRUint16 numLayers;
|
||||
};
|
||||
|
||||
struct COLRLayerRecord {
|
||||
AutoSwap_PRUint16 glyphId;
|
||||
AutoSwap_PRUint16 paletteEntryIndex;
|
||||
};
|
||||
|
||||
struct CPALHeaderVersion0 {
|
||||
AutoSwap_PRUint16 version;
|
||||
AutoSwap_PRUint16 numPaletteEntries;
|
||||
AutoSwap_PRUint16 numPalettes;
|
||||
AutoSwap_PRUint16 numColorRecords;
|
||||
AutoSwap_PRUint32 offsetFirstColorRecord;
|
||||
};
|
||||
|
||||
// sRGB color space
|
||||
struct CPALColorRecord {
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t alpha;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
bool COLRFonts::ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL) {
|
||||
unsigned int colrLength;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &colrLength));
|
||||
unsigned int cpalLength;
|
||||
const CPALHeaderVersion0* cpal = reinterpret_cast<const CPALHeaderVersion0*>(
|
||||
hb_blob_get_data(aCPAL, &cpalLength));
|
||||
|
||||
if (!colr || !cpal || !colrLength || !cpalLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uint16_t(colr->version) != 0 || uint16_t(cpal->version) != 0) {
|
||||
// We only support version 0 headers.
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t offsetBaseGlyphRecord = colr->offsetBaseGlyphRecord;
|
||||
const uint16_t numBaseGlyphRecord = colr->numBaseGlyphRecord;
|
||||
const uint32_t offsetLayerRecord = colr->offsetLayerRecord;
|
||||
const uint16_t numLayerRecords = colr->numLayerRecords;
|
||||
|
||||
const uint32_t offsetFirstColorRecord = cpal->offsetFirstColorRecord;
|
||||
const uint16_t numColorRecords = cpal->numColorRecords;
|
||||
const uint32_t numPaletteEntries = cpal->numPaletteEntries;
|
||||
|
||||
if (offsetBaseGlyphRecord >= colrLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offsetLayerRecord >= colrLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offsetFirstColorRecord >= cpalLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!numPaletteEntries) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(COLRBaseGlyphRecord) * numBaseGlyphRecord >
|
||||
colrLength - offsetBaseGlyphRecord) {
|
||||
// COLR base glyph record will be overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(COLRLayerRecord) * numLayerRecords >
|
||||
colrLength - offsetLayerRecord) {
|
||||
// COLR layer record will be overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(CPALColorRecord) * numColorRecords >
|
||||
cpalLength - offsetFirstColorRecord) {
|
||||
// CPAL color record will be overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
if (numPaletteEntries * uint16_t(cpal->numPalettes) != numColorRecords) {
|
||||
// palette of CPAL color record will be overflow.
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t lastGlyphId = 0;
|
||||
const COLRBaseGlyphRecord* baseGlyph =
|
||||
reinterpret_cast<const COLRBaseGlyphRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(colr) + offsetBaseGlyphRecord);
|
||||
|
||||
for (uint16_t i = 0; i < numBaseGlyphRecord; i++, baseGlyph++) {
|
||||
const uint32_t firstLayerIndex = baseGlyph->firstLayerIndex;
|
||||
const uint16_t numLayers = baseGlyph->numLayers;
|
||||
const uint16_t glyphId = baseGlyph->glyphId;
|
||||
|
||||
if (lastGlyphId && lastGlyphId >= glyphId) {
|
||||
// glyphId must be sorted
|
||||
return false;
|
||||
}
|
||||
lastGlyphId = glyphId;
|
||||
|
||||
if (!numLayers) {
|
||||
// no layer
|
||||
return false;
|
||||
}
|
||||
if (firstLayerIndex + numLayers > numLayerRecords) {
|
||||
// layer length of target glyph is overflow
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const COLRLayerRecord* layer = reinterpret_cast<const COLRLayerRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(colr) + offsetLayerRecord);
|
||||
|
||||
for (uint16_t i = 0; i < numLayerRecords; i++, layer++) {
|
||||
if (uint16_t(layer->paletteEntryIndex) >= numPaletteEntries &&
|
||||
uint16_t(layer->paletteEntryIndex) != 0xFFFF) {
|
||||
// CPAL palette entry record is overflow
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int CompareBaseGlyph(const void* key, const void* data) {
|
||||
uint32_t glyphId = (uint32_t)(uintptr_t)key;
|
||||
const COLRBaseGlyphRecord* baseGlyph =
|
||||
reinterpret_cast<const COLRBaseGlyphRecord*>(data);
|
||||
uint32_t baseGlyphId = uint16_t(baseGlyph->glyphId);
|
||||
|
||||
if (baseGlyphId == glyphId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return baseGlyphId > glyphId ? -1 : 1;
|
||||
}
|
||||
|
||||
static COLRBaseGlyphRecord* LookForBaseGlyphRecord(const COLRHeader* aCOLR,
|
||||
uint32_t aGlyphId) {
|
||||
const uint8_t* baseGlyphRecords = reinterpret_cast<const uint8_t*>(aCOLR) +
|
||||
uint32_t(aCOLR->offsetBaseGlyphRecord);
|
||||
// BaseGlyphRecord is sorted by glyphId
|
||||
return reinterpret_cast<COLRBaseGlyphRecord*>(
|
||||
bsearch((void*)(uintptr_t)aGlyphId, baseGlyphRecords,
|
||||
uint16_t(aCOLR->numBaseGlyphRecord), sizeof(COLRBaseGlyphRecord),
|
||||
CompareBaseGlyph));
|
||||
}
|
||||
|
||||
bool COLRFonts::GetColorGlyphLayers(
|
||||
hb_blob_t* aCOLR, hb_blob_t* aCPAL, uint32_t aGlyphId,
|
||||
const mozilla::gfx::DeviceColor& aDefaultColor, nsTArray<uint16_t>& aGlyphs,
|
||||
nsTArray<mozilla::gfx::DeviceColor>& aColors) {
|
||||
unsigned int blobLength;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &blobLength));
|
||||
MOZ_ASSERT(colr, "Cannot get COLR raw data");
|
||||
MOZ_ASSERT(blobLength, "Found COLR data, but length is 0");
|
||||
|
||||
COLRBaseGlyphRecord* baseGlyph = LookForBaseGlyphRecord(colr, aGlyphId);
|
||||
if (!baseGlyph) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CPALHeaderVersion0* cpal = reinterpret_cast<const CPALHeaderVersion0*>(
|
||||
hb_blob_get_data(aCPAL, &blobLength));
|
||||
MOZ_ASSERT(cpal, "Cannot get CPAL raw data");
|
||||
MOZ_ASSERT(blobLength, "Found CPAL data, but length is 0");
|
||||
|
||||
const COLRLayerRecord* layer = reinterpret_cast<const COLRLayerRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(colr) +
|
||||
uint32_t(colr->offsetLayerRecord) +
|
||||
sizeof(COLRLayerRecord) * uint16_t(baseGlyph->firstLayerIndex));
|
||||
const uint16_t numLayers = baseGlyph->numLayers;
|
||||
const uint32_t offsetFirstColorRecord = cpal->offsetFirstColorRecord;
|
||||
|
||||
for (uint16_t layerIndex = 0; layerIndex < numLayers; layerIndex++) {
|
||||
aGlyphs.AppendElement(uint16_t(layer->glyphId));
|
||||
if (uint16_t(layer->paletteEntryIndex) == 0xFFFF) {
|
||||
aColors.AppendElement(aDefaultColor);
|
||||
} else {
|
||||
const CPALColorRecord* color = reinterpret_cast<const CPALColorRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(cpal) + offsetFirstColorRecord +
|
||||
sizeof(CPALColorRecord) * uint16_t(layer->paletteEntryIndex));
|
||||
aColors.AppendElement(
|
||||
mozilla::gfx::ToDeviceColor(mozilla::gfx::sRGBColor::FromU8(
|
||||
color->red, color->green, color->blue, color->alpha)));
|
||||
}
|
||||
layer++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool COLRFonts::HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId) {
|
||||
unsigned int blobLength;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &blobLength));
|
||||
MOZ_ASSERT(colr, "Cannot get COLR raw data");
|
||||
MOZ_ASSERT(blobLength, "Found COLR data, but length is 0");
|
||||
|
||||
return LookForBaseGlyphRecord(colr, aGlyphId);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef COLR_FONTS_H
|
||||
#define COLR_FONTS_H
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
struct hb_blob_t;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
struct DeviceColor;
|
||||
|
||||
class COLRFonts {
|
||||
public:
|
||||
// for color layer from glyph using COLR and CPAL tables
|
||||
static bool ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL);
|
||||
static bool GetColorGlyphLayers(
|
||||
hb_blob_t* aCOLR, hb_blob_t* aCPAL, uint32_t aGlyphId,
|
||||
const mozilla::gfx::DeviceColor& aDefaultColor,
|
||||
nsTArray<uint16_t>& aGlyphs,
|
||||
nsTArray<mozilla::gfx::DeviceColor>& aColors);
|
||||
static bool HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // COLR_FONTS_H
|
|
@ -389,7 +389,7 @@ bool gfxFontEntry::TryGetColorGlyphs() {
|
|||
auto* colr = GetFontTable(TRUETYPE_TAG('C', 'O', 'L', 'R'));
|
||||
auto* cpal = colr ? GetFontTable(TRUETYPE_TAG('C', 'P', 'A', 'L')) : nullptr;
|
||||
|
||||
if (colr && cpal && gfxFontUtils::ValidateColorGlyphs(colr, cpal)) {
|
||||
if (colr && cpal && gfx::COLRFonts::ValidateColorGlyphs(colr, cpal)) {
|
||||
if (!mCOLR.compareExchange(nullptr, colr)) {
|
||||
hb_blob_destroy(colr);
|
||||
}
|
||||
|
@ -1043,7 +1043,7 @@ bool gfxFontEntry::GetColorLayersInfo(
|
|||
uint32_t aGlyphId, const mozilla::gfx::DeviceColor& aDefaultColor,
|
||||
nsTArray<uint16_t>& aLayerGlyphs,
|
||||
nsTArray<mozilla::gfx::DeviceColor>& aLayerColors) {
|
||||
return gfxFontUtils::GetColorGlyphLayers(GetCOLR(), GetCPAL(), aGlyphId,
|
||||
return gfx::COLRFonts::GetColorGlyphLayers(GetCOLR(), GetCPAL(), aGlyphId,
|
||||
aDefaultColor, aLayerGlyphs,
|
||||
aLayerColors);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <math.h>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include "COLRFonts.h"
|
||||
#include "ThebesRLBoxTypes.h"
|
||||
#include "gfxFontUtils.h"
|
||||
#include "gfxFontVariations.h"
|
||||
|
@ -274,7 +275,7 @@ class gfxFontEntry {
|
|||
nsTArray<mozilla::gfx::DeviceColor>& layerColors);
|
||||
bool HasColorLayersForGlyph(uint32_t aGlyphId) {
|
||||
MOZ_ASSERT(GetCOLR());
|
||||
return gfxFontUtils::HasColorLayersForGlyph(GetCOLR(), aGlyphId);
|
||||
return mozilla::gfx::COLRFonts::HasColorLayersForGlyph(GetCOLR(), aGlyphId);
|
||||
}
|
||||
|
||||
bool HasColorBitmapTable() {
|
||||
|
|
|
@ -1555,212 +1555,6 @@ nsresult gfxFontUtils::ReadNames(const char* aNameData, uint32_t aDataLen,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct COLRBaseGlyphRecord {
|
||||
AutoSwap_PRUint16 glyphId;
|
||||
AutoSwap_PRUint16 firstLayerIndex;
|
||||
AutoSwap_PRUint16 numLayers;
|
||||
};
|
||||
|
||||
struct COLRLayerRecord {
|
||||
AutoSwap_PRUint16 glyphId;
|
||||
AutoSwap_PRUint16 paletteEntryIndex;
|
||||
};
|
||||
|
||||
// sRGB color space
|
||||
struct CPALColorRecord {
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t alpha;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
bool gfxFontUtils::ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL) {
|
||||
unsigned int colrLength;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &colrLength));
|
||||
unsigned int cpalLength;
|
||||
const CPALHeaderVersion0* cpal = reinterpret_cast<const CPALHeaderVersion0*>(
|
||||
hb_blob_get_data(aCPAL, &cpalLength));
|
||||
|
||||
if (!colr || !cpal || !colrLength || !cpalLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uint16_t(colr->version) != 0 || uint16_t(cpal->version) != 0) {
|
||||
// We only support version 0 headers.
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t offsetBaseGlyphRecord = colr->offsetBaseGlyphRecord;
|
||||
const uint16_t numBaseGlyphRecord = colr->numBaseGlyphRecord;
|
||||
const uint32_t offsetLayerRecord = colr->offsetLayerRecord;
|
||||
const uint16_t numLayerRecords = colr->numLayerRecords;
|
||||
|
||||
const uint32_t offsetFirstColorRecord = cpal->offsetFirstColorRecord;
|
||||
const uint16_t numColorRecords = cpal->numColorRecords;
|
||||
const uint32_t numPaletteEntries = cpal->numPaletteEntries;
|
||||
|
||||
if (offsetBaseGlyphRecord >= colrLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offsetLayerRecord >= colrLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offsetFirstColorRecord >= cpalLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!numPaletteEntries) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(COLRBaseGlyphRecord) * numBaseGlyphRecord >
|
||||
colrLength - offsetBaseGlyphRecord) {
|
||||
// COLR base glyph record will be overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(COLRLayerRecord) * numLayerRecords >
|
||||
colrLength - offsetLayerRecord) {
|
||||
// COLR layer record will be overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(CPALColorRecord) * numColorRecords >
|
||||
cpalLength - offsetFirstColorRecord) {
|
||||
// CPAL color record will be overflow
|
||||
return false;
|
||||
}
|
||||
|
||||
if (numPaletteEntries * uint16_t(cpal->numPalettes) != numColorRecords) {
|
||||
// palette of CPAL color record will be overflow.
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t lastGlyphId = 0;
|
||||
const COLRBaseGlyphRecord* baseGlyph =
|
||||
reinterpret_cast<const COLRBaseGlyphRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(colr) + offsetBaseGlyphRecord);
|
||||
|
||||
for (uint16_t i = 0; i < numBaseGlyphRecord; i++, baseGlyph++) {
|
||||
const uint32_t firstLayerIndex = baseGlyph->firstLayerIndex;
|
||||
const uint16_t numLayers = baseGlyph->numLayers;
|
||||
const uint16_t glyphId = baseGlyph->glyphId;
|
||||
|
||||
if (lastGlyphId && lastGlyphId >= glyphId) {
|
||||
// glyphId must be sorted
|
||||
return false;
|
||||
}
|
||||
lastGlyphId = glyphId;
|
||||
|
||||
if (!numLayers) {
|
||||
// no layer
|
||||
return false;
|
||||
}
|
||||
if (firstLayerIndex + numLayers > numLayerRecords) {
|
||||
// layer length of target glyph is overflow
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const COLRLayerRecord* layer = reinterpret_cast<const COLRLayerRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(colr) + offsetLayerRecord);
|
||||
|
||||
for (uint16_t i = 0; i < numLayerRecords; i++, layer++) {
|
||||
if (uint16_t(layer->paletteEntryIndex) >= numPaletteEntries &&
|
||||
uint16_t(layer->paletteEntryIndex) != 0xFFFF) {
|
||||
// CPAL palette entry record is overflow
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int CompareBaseGlyph(const void* key, const void* data) {
|
||||
uint32_t glyphId = (uint32_t)(uintptr_t)key;
|
||||
const COLRBaseGlyphRecord* baseGlyph =
|
||||
reinterpret_cast<const COLRBaseGlyphRecord*>(data);
|
||||
uint32_t baseGlyphId = uint16_t(baseGlyph->glyphId);
|
||||
|
||||
if (baseGlyphId == glyphId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return baseGlyphId > glyphId ? -1 : 1;
|
||||
}
|
||||
|
||||
static COLRBaseGlyphRecord* LookForBaseGlyphRecord(const COLRHeader* aCOLR,
|
||||
uint32_t aGlyphId) {
|
||||
const uint8_t* baseGlyphRecords = reinterpret_cast<const uint8_t*>(aCOLR) +
|
||||
uint32_t(aCOLR->offsetBaseGlyphRecord);
|
||||
// BaseGlyphRecord is sorted by glyphId
|
||||
return reinterpret_cast<COLRBaseGlyphRecord*>(
|
||||
bsearch((void*)(uintptr_t)aGlyphId, baseGlyphRecords,
|
||||
uint16_t(aCOLR->numBaseGlyphRecord), sizeof(COLRBaseGlyphRecord),
|
||||
CompareBaseGlyph));
|
||||
}
|
||||
|
||||
bool gfxFontUtils::GetColorGlyphLayers(
|
||||
hb_blob_t* aCOLR, hb_blob_t* aCPAL, uint32_t aGlyphId,
|
||||
const mozilla::gfx::DeviceColor& aDefaultColor, nsTArray<uint16_t>& aGlyphs,
|
||||
nsTArray<mozilla::gfx::DeviceColor>& aColors) {
|
||||
unsigned int blobLength;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &blobLength));
|
||||
MOZ_ASSERT(colr, "Cannot get COLR raw data");
|
||||
MOZ_ASSERT(blobLength, "Found COLR data, but length is 0");
|
||||
|
||||
COLRBaseGlyphRecord* baseGlyph = LookForBaseGlyphRecord(colr, aGlyphId);
|
||||
if (!baseGlyph) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CPALHeaderVersion0* cpal = reinterpret_cast<const CPALHeaderVersion0*>(
|
||||
hb_blob_get_data(aCPAL, &blobLength));
|
||||
MOZ_ASSERT(cpal, "Cannot get CPAL raw data");
|
||||
MOZ_ASSERT(blobLength, "Found CPAL data, but length is 0");
|
||||
|
||||
const COLRLayerRecord* layer = reinterpret_cast<const COLRLayerRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(colr) +
|
||||
uint32_t(colr->offsetLayerRecord) +
|
||||
sizeof(COLRLayerRecord) * uint16_t(baseGlyph->firstLayerIndex));
|
||||
const uint16_t numLayers = baseGlyph->numLayers;
|
||||
const uint32_t offsetFirstColorRecord = cpal->offsetFirstColorRecord;
|
||||
|
||||
for (uint16_t layerIndex = 0; layerIndex < numLayers; layerIndex++) {
|
||||
aGlyphs.AppendElement(uint16_t(layer->glyphId));
|
||||
if (uint16_t(layer->paletteEntryIndex) == 0xFFFF) {
|
||||
aColors.AppendElement(aDefaultColor);
|
||||
} else {
|
||||
const CPALColorRecord* color = reinterpret_cast<const CPALColorRecord*>(
|
||||
reinterpret_cast<const uint8_t*>(cpal) + offsetFirstColorRecord +
|
||||
sizeof(CPALColorRecord) * uint16_t(layer->paletteEntryIndex));
|
||||
aColors.AppendElement(
|
||||
mozilla::gfx::ToDeviceColor(mozilla::gfx::sRGBColor::FromU8(
|
||||
color->red, color->green, color->blue, color->alpha)));
|
||||
}
|
||||
layer++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gfxFontUtils::HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId) {
|
||||
unsigned int blobLength;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &blobLength));
|
||||
MOZ_ASSERT(colr, "Cannot get COLR raw data");
|
||||
MOZ_ASSERT(blobLength, "Found COLR data, but length is 0");
|
||||
|
||||
return LookForBaseGlyphRecord(colr, aGlyphId);
|
||||
}
|
||||
|
||||
void gfxFontUtils::GetVariationData(
|
||||
gfxFontEntry* aFontEntry, nsTArray<gfxFontVariationAxis>* aAxes,
|
||||
nsTArray<gfxFontVariationInstance>* aInstances) {
|
||||
|
|
|
@ -31,9 +31,6 @@ struct gfxFontVariationInstance;
|
|||
namespace mozilla {
|
||||
class Encoding;
|
||||
class ServoStyleSet;
|
||||
namespace gfx {
|
||||
struct DeviceColor;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
/* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
|
||||
|
@ -790,22 +787,6 @@ struct KernTableSubtableHeaderVersion1 {
|
|||
AutoSwap_PRUint16 tupleIndex;
|
||||
};
|
||||
|
||||
struct COLRHeader {
|
||||
AutoSwap_PRUint16 version;
|
||||
AutoSwap_PRUint16 numBaseGlyphRecord;
|
||||
AutoSwap_PRUint32 offsetBaseGlyphRecord;
|
||||
AutoSwap_PRUint32 offsetLayerRecord;
|
||||
AutoSwap_PRUint16 numLayerRecords;
|
||||
};
|
||||
|
||||
struct CPALHeaderVersion0 {
|
||||
AutoSwap_PRUint16 version;
|
||||
AutoSwap_PRUint16 numPaletteEntries;
|
||||
AutoSwap_PRUint16 numPalettes;
|
||||
AutoSwap_PRUint16 numColorRecords;
|
||||
AutoSwap_PRUint32 offsetFirstColorRecord;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
// Return just the highest bit of the given value, i.e., the highest
|
||||
|
@ -1151,15 +1132,6 @@ class gfxFontUtils {
|
|||
// generate a unique font name
|
||||
static nsresult MakeUniqueUserFontName(nsAString& aName);
|
||||
|
||||
// for color layer from glyph using COLR and CPAL tables
|
||||
static bool ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL);
|
||||
static bool GetColorGlyphLayers(
|
||||
hb_blob_t* aCOLR, hb_blob_t* aCPAL, uint32_t aGlyphId,
|
||||
const mozilla::gfx::DeviceColor& aDefaultColor,
|
||||
nsTArray<uint16_t>& aGlyphs,
|
||||
nsTArray<mozilla::gfx::DeviceColor>& aColors);
|
||||
static bool HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId);
|
||||
|
||||
// Helper used to implement gfxFontEntry::GetVariation{Axes,Instances} for
|
||||
// platforms where the native font APIs don't provide the info we want
|
||||
// in a convenient form, or when native APIs are too expensive.
|
||||
|
|
|
@ -17,6 +17,7 @@ XPIDL_SOURCES += [
|
|||
XPIDL_MODULE = "gfx"
|
||||
|
||||
EXPORTS += [
|
||||
"COLRFonts.h",
|
||||
"DrawMode.h",
|
||||
"gfx2DGlue.h",
|
||||
"gfxAlphaRecovery.h",
|
||||
|
@ -195,6 +196,7 @@ SOURCES += [
|
|||
|
||||
UNIFIED_SOURCES += [
|
||||
"CJKCompatSVS.cpp",
|
||||
"COLRFonts.cpp",
|
||||
"gfxAlphaRecovery.cpp",
|
||||
"gfxBaseSharedMemorySurface.cpp",
|
||||
"gfxBlur.cpp",
|
||||
|
|
Загрузка…
Ссылка в новой задаче