mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
f9646c70e9
commit
bf27afea13
8 files changed
+137
-56
No files matched your search
+17
-10
@@ -89,8 +89,8 @@ a:focus-visible {
|
|||||||
display: flex;
|
display: flex;
|
||||||
max-height: 40dvh;
|
max-height: 40dvh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
gap: 12px;
|
gap: 8px;
|
||||||
padding: 8px 12px 6px;
|
padding: 8px 10px 6px;
|
||||||
border-bottom: 1px solid var(--line);
|
border-bottom: 1px solid var(--line);
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -105,18 +105,15 @@ a:focus-visible {
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
grid-template-columns: repeat(3, max-content);
|
grid-template-columns: repeat(3, max-content);
|
||||||
grid-template-rows: repeat(2, 28px) 16px;
|
grid-template-rows: repeat(2, 28px) 16px;
|
||||||
column-gap: 6px;
|
column-gap: 4px;
|
||||||
row-gap: 4px;
|
row-gap: 4px;
|
||||||
padding-right: 12px;
|
padding-right: 8px;
|
||||||
border-right: 1px solid var(--line);
|
border-right: 1px solid var(--line);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-file,
|
.editor-file,
|
||||||
.editor-erase,
|
.editor-erase,
|
||||||
.editor-paragraph,
|
.editor-image {
|
||||||
.editor-image,
|
|
||||||
.editor-group:has(#textFont),
|
|
||||||
.editor-group:has(#shapeFill) {
|
|
||||||
grid-template-columns: repeat(2, max-content);
|
grid-template-columns: repeat(2, max-content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,14 +189,19 @@ a:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-group:has(#textFont) {
|
.editor-group:has(#textFont) {
|
||||||
grid-template-columns: 100px 54px;
|
grid-template-columns: 102px 54px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-paragraph {
|
.editor-paragraph {
|
||||||
width: 218px;
|
width: 194px;
|
||||||
grid-template-columns: 54px minmax(0, 1fr);
|
grid-template-columns: 54px minmax(0, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-group:has(#shapeFill) {
|
||||||
|
width: 180px;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.editor-file #saveButton {
|
.editor-file #saveButton {
|
||||||
grid-row: 1 / 3;
|
grid-row: 1 / 3;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -308,6 +310,10 @@ a:focus-visible {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shape-paint .color-input {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.shape-paint,
|
.shape-paint,
|
||||||
.shape-paint label {
|
.shape-paint label {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -322,6 +328,7 @@ a:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-group:last-child {
|
.editor-group:last-child {
|
||||||
|
padding-right: 0;
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+31
-9
@@ -53,6 +53,7 @@ const state = {
|
|||||||
navigationScroll: new Map(),
|
navigationScroll: new Map(),
|
||||||
fontSyncPending: false,
|
fontSyncPending: false,
|
||||||
fontCatalogLoading: false,
|
fontCatalogLoading: false,
|
||||||
|
fontFacesLoading: false,
|
||||||
fontRenderPending: false,
|
fontRenderPending: false,
|
||||||
fontSyncing: false,
|
fontSyncing: false,
|
||||||
doc: null,
|
doc: null,
|
||||||
@@ -1001,23 +1002,40 @@ function editorFonts(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function loadEditorFonts() {
|
async function loadEditorFonts() {
|
||||||
const local = fontManager.canReadLocal() && !fontManager.catalogLoaded && fontManager.permission !== "denied";
|
const tasks = [];
|
||||||
if (state.fontCatalogLoading || !local && !fontManager.userFonts.some(font => font.enabled && !font.faces)) return;
|
if (!state.fontCatalogLoading && fontManager.canReadLocal() && !fontManager.catalogLoaded && fontManager.permission !== "denied") {
|
||||||
state.fontCatalogLoading = true;
|
state.fontCatalogLoading = true;
|
||||||
|
tasks.push((async () => {
|
||||||
try {
|
try {
|
||||||
if (local) {
|
await fontManager.queryLocal();
|
||||||
try { await fontManager.queryLocal(); }
|
refreshEditorFonts();
|
||||||
catch (err) { setStatus(err?.name === "NotAllowedError" ? "字体尚未授权" : String(err.message || err)); }
|
} catch (err) {
|
||||||
|
setStatus(err?.name === "NotAllowedError" ? "字体尚未授权" : String(err.message || err));
|
||||||
|
} finally {
|
||||||
|
state.fontCatalogLoading = false;
|
||||||
}
|
}
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
if (!state.fontFacesLoading && fontManager.userFonts.some(font => font.enabled && !font.faces)) {
|
||||||
|
state.fontFacesLoading = true;
|
||||||
|
tasks.push((async () => {
|
||||||
|
try {
|
||||||
await fontManager.loadFaces(data => callWASM("ofdgoFontFaces", data));
|
await fontManager.loadFaces(data => callWASM("ofdgoFontFaces", data));
|
||||||
|
refreshEditorFonts();
|
||||||
|
} finally {
|
||||||
|
state.fontFacesLoading = false;
|
||||||
|
}
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
await Promise.all(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshEditorFonts() {
|
||||||
const open = fontPicker.open;
|
const open = fontPicker.open;
|
||||||
const selected = state.textFonts[Number(fontPicker.value)];
|
const selected = state.textFonts[Number(fontPicker.value)];
|
||||||
const query = el.textFont.value === (selected?.fullName || selected?.name || "") ? "" : el.textFont.value;
|
const query = el.textFont.value === (selected?.fullName || selected?.name || "") ? "" : el.textFont.value;
|
||||||
updateTextFonts(canvasEditor.selected, true);
|
updateTextFonts(canvasEditor.selected, true);
|
||||||
if (open && !el.textFont.disabled) { if (query) el.textFont.value = query; fontPicker.show(query); }
|
if (open && !el.textFont.disabled) { if (query) el.textFont.value = query; fontPicker.show(query, false); }
|
||||||
} finally {
|
|
||||||
state.fontCatalogLoading = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readTextFont(font) {
|
async function readTextFont(font) {
|
||||||
@@ -4139,6 +4157,10 @@ function fontResult(font) {
|
|||||||
if (font.matched) {
|
if (font.matched) {
|
||||||
parts.push(font.embedded || font.status === "embedded" ? `内嵌 ${font.matched}` : `匹配 ${font.matched}`);
|
parts.push(font.embedded || font.status === "embedded" ? `内嵌 ${font.matched}` : `匹配 ${font.matched}`);
|
||||||
}
|
}
|
||||||
|
if (font.matchedFace?.fullName) {
|
||||||
|
parts.push(font.matchedFace.fullName);
|
||||||
|
if (font.matchedFace.index > 0) parts.push(`索引 ${font.matchedFace.index}`);
|
||||||
|
}
|
||||||
if (font.detail) {
|
if (font.detail) {
|
||||||
parts.push(font.detail);
|
parts.push(font.detail);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export class FontPicker {
|
|||||||
return font.embedded ? "内嵌" : font.file || ["stored", "upload"].includes(font.source) ? "上传" : "系统";
|
return font.embedded ? "内嵌" : font.file || ["stored", "upload"].includes(font.source) ? "上传" : "系统";
|
||||||
}
|
}
|
||||||
|
|
||||||
show(query = "") {
|
show(query = "", load = true) {
|
||||||
if (this.input.disabled) return;
|
if (this.input.disabled) return;
|
||||||
const normalize = value => value.normalize("NFKC").toLocaleLowerCase().replace(/\s+/g, " ").trim();
|
const normalize = value => value.normalize("NFKC").toLocaleLowerCase().replace(/\s+/g, " ").trim();
|
||||||
const terms = normalize(query).split(" ").filter(Boolean);
|
const terms = normalize(query).split(" ").filter(Boolean);
|
||||||
@@ -95,7 +95,7 @@ export class FontPicker {
|
|||||||
this.position();
|
this.position();
|
||||||
const selected = this.matches.findIndex(({ font, index }) => !font.disabled && String(index) === this.value);
|
const selected = this.matches.findIndex(({ font, index }) => !font.disabled && String(index) === this.value);
|
||||||
this.activate(selected < 0 ? this.matches.findIndex(({ font }) => !font.disabled) : selected);
|
this.activate(selected < 0 ? this.matches.findIndex(({ font }) => !font.disabled) : selected);
|
||||||
this.onOpen?.();
|
if (load) this.onOpen?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
position() {
|
position() {
|
||||||
@@ -316,8 +316,9 @@ export class FontManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadFaces(inspect) {
|
async loadFaces(inspect) {
|
||||||
for (const file of this.userFonts) {
|
while (true) {
|
||||||
if (!file.enabled || file.faces) continue;
|
const file = this.userFonts.find(font => font.enabled && !font.faces);
|
||||||
|
if (!file) return;
|
||||||
try { file.faces = await inspect(await this.read(file)); }
|
try { file.faces = await inspect(await this.read(file)); }
|
||||||
catch { file.faces = []; }
|
catch { file.faces = []; }
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-8
@@ -50,7 +50,20 @@ func (f FontFile) Faces() ([]FontFace, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
records, values := fontNameValues(tables["name"])
|
face := fontFaceInfo(tables["name"], index)
|
||||||
|
if face.FullName == "" {
|
||||||
|
return nil, fmt.Errorf("font %d has no usable name", index)
|
||||||
|
}
|
||||||
|
faces = append(faces, face)
|
||||||
|
}
|
||||||
|
return faces, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontFaceInfo 从名称表读取字体信息
|
||||||
|
// 入参: data 名称表数据, index 零起始字体索引
|
||||||
|
// 返回: FontFace 字体信息
|
||||||
|
func fontFaceInfo(data []byte, index int) FontFace {
|
||||||
|
records, values := fontNameValues(data)
|
||||||
name := func(ids ...uint16) string {
|
name := func(ids ...uint16) string {
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
for _, record := range records {
|
for _, record := range records {
|
||||||
@@ -63,13 +76,7 @@ func (f FontFile) Faces() ([]FontFace, error) {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
face := FontFace{Index: index, FullName: name(4, 6, 16, 1), Family: name(16, 1), Style: name(17, 2), PostScriptName: name(6), Names: fontNamesFromTable(tables["name"])}
|
return FontFace{Index: index, FullName: name(4, 6, 16, 1), Family: name(16, 1), Style: name(17, 2), PostScriptName: name(6), Names: fontNamesFromTable(data)}
|
||||||
if face.FullName == "" {
|
|
||||||
return nil, fmt.Errorf("font %d has no usable name", index)
|
|
||||||
}
|
|
||||||
faces = append(faces, face)
|
|
||||||
}
|
|
||||||
return faces, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Face 提取指定字体,返回独立的OpenType数据,可用于预览或AddFont,且不修改原文件
|
// Face 提取指定字体,返回独立的OpenType数据,可用于预览或AddFont,且不修改原文件
|
||||||
|
|||||||
+52
-15
@@ -20,7 +20,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/tdewolff/font"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -34,7 +37,7 @@ const (
|
|||||||
FontStatusMissing = "missing"
|
FontStatusMissing = "missing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FontInfo OFD字体诊断信息
|
// FontInfo OFD字体诊断信息,MatchedFace为实际匹配字体及原文件中的零起始索引,无法读取时为空
|
||||||
type FontInfo struct {
|
type FontInfo struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
FontName string `json:"fontName"`
|
FontName string `json:"fontName"`
|
||||||
@@ -44,6 +47,7 @@ type FontInfo struct {
|
|||||||
Embedded bool `json:"embedded"`
|
Embedded bool `json:"embedded"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Matched string `json:"matched"`
|
Matched string `json:"matched"`
|
||||||
|
MatchedFace *FontFace `json:"matchedFace,omitempty"`
|
||||||
Detail string `json:"detail"`
|
Detail string `json:"detail"`
|
||||||
Used int `json:"used"`
|
Used int `json:"used"`
|
||||||
}
|
}
|
||||||
@@ -100,6 +104,48 @@ func (r *Reader) FontData(id string) ([]byte, error) {
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// embeddedFontFace 按资源缓存内嵌字体名称并返回独立副本,不解析字形轮廓
|
||||||
|
// 入参: of OFD字体定义
|
||||||
|
// 返回: *FontFace 字体信息, error 资源读取错误
|
||||||
|
func (r *Reader) embeddedFontFace(of Font) (*FontFace, error) {
|
||||||
|
name := r.ResPath(of.FontFile)
|
||||||
|
faces, ok := r.fontFaces[name]
|
||||||
|
if !ok {
|
||||||
|
data, err := r.readFile(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if data, err = font.ToSFNT(data); err == nil {
|
||||||
|
if count, err := fontFileCount(data); err == nil {
|
||||||
|
faces = make([]*FontFace, count)
|
||||||
|
for index := range faces {
|
||||||
|
if tables, err := fontFileTables(data, index); err == nil {
|
||||||
|
info := fontFaceInfo(tables["name"], index)
|
||||||
|
faces[index] = &info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.fontFaces[name] = faces
|
||||||
|
}
|
||||||
|
if len(faces) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
names := make([][]string, len(faces))
|
||||||
|
for index, face := range faces {
|
||||||
|
if face != nil {
|
||||||
|
names[index] = face.Names
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index := fontNameIndex(names, []string{of.FontName, of.FamilyName}, of.Bold, of.Italic)
|
||||||
|
if faces[index] == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
face := *faces[index]
|
||||||
|
face.Names = slices.Clone(face.Names)
|
||||||
|
return &face, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FontInfos 获取OFD字体诊断信息
|
// FontInfos 获取OFD字体诊断信息
|
||||||
// 返回: []FontInfo 字体诊断列表, error 错误信息
|
// 返回: []FontInfo 字体诊断列表, error 错误信息
|
||||||
func (r *Renderer) FontInfos() ([]FontInfo, error) {
|
func (r *Renderer) FontInfos() ([]FontInfo, error) {
|
||||||
@@ -194,22 +240,11 @@ func (r *Renderer) fontInfo(font Font) FontInfo {
|
|||||||
Embedded: font.FontFile != "",
|
Embedded: font.FontFile != "",
|
||||||
}
|
}
|
||||||
if info.Embedded {
|
if info.Embedded {
|
||||||
name := r.Reader.ResPath(font.FontFile)
|
face, err := r.Reader.embeddedFontFace(font)
|
||||||
var err error
|
|
||||||
if !r.Reader.fontFilesChecked[name] {
|
|
||||||
var file io.ReadCloser
|
|
||||||
file, err = r.Reader.openFile(name)
|
|
||||||
if err == nil {
|
|
||||||
_, err = io.Copy(io.Discard, file)
|
|
||||||
file.Close()
|
|
||||||
if err == nil {
|
|
||||||
r.Reader.fontFilesChecked[name] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
info.Status = FontStatusEmbedded
|
info.Status = FontStatusEmbedded
|
||||||
info.Matched = path.Base(font.FontFile)
|
info.Matched = path.Base(font.FontFile)
|
||||||
|
info.MatchedFace = face
|
||||||
info.Detail = "使用内嵌字体文件"
|
info.Detail = "使用内嵌字体文件"
|
||||||
} else {
|
} else {
|
||||||
info.Status = FontStatusMissing
|
info.Status = FontStatusMissing
|
||||||
@@ -217,8 +252,10 @@ func (r *Renderer) fontInfo(font Font) FontInfo {
|
|||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
if source, ok := r.fontSourceMatch(font.ID, &font); ok {
|
if source, family := r.fontSourceMatch(font.ID, &font); family != nil {
|
||||||
info.Matched = source.name
|
info.Matched = source.name
|
||||||
|
face := fontFaceInfo(family.Face(12, canvasFontStyle(&font)).Font.SFNT.Tables["name"], source.face)
|
||||||
|
info.MatchedFace = &face
|
||||||
if source.exact {
|
if source.exact {
|
||||||
info.Status = FontStatusMatched
|
info.Status = FontStatusMatched
|
||||||
info.Detail = "使用外部字体文件"
|
info.Detail = "使用外部字体文件"
|
||||||
|
|||||||
@@ -214,26 +214,26 @@ func appendFontSource(sources []fontSource, seen map[fontSourceKey]bool, source
|
|||||||
|
|
||||||
// fontSourceMatch 获取匹配的字体来源
|
// fontSourceMatch 获取匹配的字体来源
|
||||||
// 入参: fontID 字体ID, font OFD字体定义
|
// 入参: fontID 字体ID, font OFD字体定义
|
||||||
// 返回: fontSource 字体来源, bool 是否匹配
|
// 返回: fontSource 字体来源, *canvas.FontFamily 已加载的字体族,未匹配时为空
|
||||||
func (r *Renderer) fontSourceMatch(fontID string, font *Font) (fontSource, bool) {
|
func (r *Renderer) fontSourceMatch(fontID string, font *Font) (fontSource, *canvas.FontFamily) {
|
||||||
if source, ok := r.fontSourceUsed[fontID]; ok {
|
if source, ok := r.fontSourceUsed[fontID]; ok {
|
||||||
return source, true
|
return source, r.fontMap[fontID]
|
||||||
}
|
}
|
||||||
style := canvasFontStyle(font)
|
style := canvasFontStyle(font)
|
||||||
for _, source := range r.fontSources(fontID, font, style) {
|
for _, source := range r.fontSources(fontID, font, style) {
|
||||||
key := fontCacheKey{fontSourceKey: fontSourceKey{kind: source.kind, index: source.index, name: source.name, face: source.face}, style: style}
|
key := fontCacheKey{fontSourceKey: fontSourceKey{kind: source.kind, index: source.index, name: source.name, face: source.face}, style: style}
|
||||||
if cached, ok := r.fontCache[key]; ok {
|
if cached, ok := r.fontCache[key]; ok {
|
||||||
if cached != nil {
|
if cached != nil {
|
||||||
return source, true
|
return source, cached
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
family := canvas.NewFontFamily(font.FontName)
|
family := canvas.NewFontFamily(font.FontName)
|
||||||
if r.loadFontSource(family, source, style) != nil {
|
if loaded := r.loadFontSource(family, source, style); loaded != nil {
|
||||||
return source, true
|
return source, loaded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fontSource{}, false
|
return fontSource{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadFontSource 加载字体来源
|
// loadFontSource 加载字体来源
|
||||||
|
|||||||
+8
-1
@@ -84,7 +84,14 @@ func fontFileNames(file io.ReaderAt) [][]string {
|
|||||||
// 入参: data 集合数据, names 字体名称, bold 是否粗体, italic 是否斜体
|
// 入参: data 集合数据, names 字体名称, bold 是否粗体, italic 是否斜体
|
||||||
// 返回: int 零起始字体索引
|
// 返回: int 零起始字体索引
|
||||||
func fontCollectionIndex(data []byte, names []string, bold, italic bool) int {
|
func fontCollectionIndex(data []byte, names []string, bold, italic bool) int {
|
||||||
candidates := appendFontFileNames([]fontFileCandidate{{}}, 0, fontFileNames(bytes.NewReader(data)))
|
return fontNameIndex(fontFileNames(bytes.NewReader(data)), names, bold, italic)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontNameIndex 按名称与样式选择字体索引,未匹配时保留首项
|
||||||
|
// 入参: faces 各字体名称, names 目标名称, bold 是否粗体, italic 是否斜体
|
||||||
|
// 返回: int 零起始字体索引
|
||||||
|
func fontNameIndex(faces [][]string, names []string, bold, italic bool) int {
|
||||||
|
candidates := appendFontFileNames([]fontFileCandidate{{}}, 0, faces)
|
||||||
if matches := fontFileMatches(candidates, names, bold, italic); len(matches) > 0 {
|
if matches := fontFileMatches(candidates, names, bold, italic); len(matches) > 0 {
|
||||||
return matches[0].face
|
return matches[0].face
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -37,7 +37,7 @@ type Reader struct {
|
|||||||
resourceFiles map[string]string
|
resourceFiles map[string]string
|
||||||
fontCache map[string]*Font
|
fontCache map[string]*Font
|
||||||
fontResourcesRead bool
|
fontResourcesRead bool
|
||||||
fontFilesChecked map[string]bool
|
fontFaces map[string][]*FontFace
|
||||||
colorSpaceCache map[string]*ColorSpace
|
colorSpaceCache map[string]*ColorSpace
|
||||||
drawParamCache map[string]*DrawParam
|
drawParamCache map[string]*DrawParam
|
||||||
compositeGraphicUnitCache map[string]*CompositeGraphicUnit
|
compositeGraphicUnitCache map[string]*CompositeGraphicUnit
|
||||||
@@ -87,7 +87,7 @@ func (r *Reader) initRoot() error {
|
|||||||
r.resourcesRead = make(map[string]bool)
|
r.resourcesRead = make(map[string]bool)
|
||||||
r.resourceFiles = make(map[string]string)
|
r.resourceFiles = make(map[string]string)
|
||||||
r.fontCache = make(map[string]*Font)
|
r.fontCache = make(map[string]*Font)
|
||||||
r.fontFilesChecked = make(map[string]bool)
|
r.fontFaces = make(map[string][]*FontFace)
|
||||||
r.colorSpaceCache = make(map[string]*ColorSpace)
|
r.colorSpaceCache = make(map[string]*ColorSpace)
|
||||||
r.drawParamCache = make(map[string]*DrawParam)
|
r.drawParamCache = make(map[string]*DrawParam)
|
||||||
r.compositeGraphicUnitCache = make(map[string]*CompositeGraphicUnit)
|
r.compositeGraphicUnitCache = make(map[string]*CompositeGraphicUnit)
|
||||||
|
|||||||
Reference in new issue
Block a user