Coverage Report

Created: 2024-05-20 07:14

/src/skia/tools/text/SkTextBlobTrace.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2019 Google LLC.
2
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
4
#include "tools/text/SkTextBlobTrace.h"
5
6
#include "include/core/SkData.h"
7
#include "include/core/SkFont.h"
8
#include "include/core/SkFontMgr.h"
9
#include "include/core/SkStream.h"
10
#include "include/core/SkString.h"
11
#include "include/core/SkTextBlob.h"
12
#include "include/core/SkTypeface.h"
13
#include "include/private/base/SkDebug.h"
14
#include "src/base/SkTLazy.h"
15
#include "src/core/SkChecksum.h"
16
#include "src/core/SkFontPriv.h"
17
#include "src/core/SkPtrRecorder.h"
18
#include "src/core/SkReadBuffer.h"
19
#include "src/core/SkTextBlobPriv.h"
20
#include "src/core/SkWriteBuffer.h"
21
#include "src/text/GlyphRun.h"
22
23
#include <utility>
24
25
std::vector<SkTextBlobTrace::Record> SkTextBlobTrace::CreateBlobTrace(
26
0
        SkStream* stream, sk_sp<SkFontMgr> lastResortMgr) {
27
0
    std::vector<SkTextBlobTrace::Record> trace;
28
29
0
    uint32_t typefaceCount;
30
0
    if (!stream->readU32(&typefaceCount)) {
31
0
        return trace;
32
0
    }
33
34
0
    std::vector<sk_sp<SkTypeface>> typefaceArray;
35
0
    for (uint32_t i = 0; i < typefaceCount; i++) {
36
0
        typefaceArray.push_back(SkTypeface::MakeDeserialize(stream, lastResortMgr));
37
0
    }
38
39
0
    uint32_t restOfFile;
40
0
    if (!stream->readU32(&restOfFile)) {
41
0
        return trace;
42
0
    }
43
0
    sk_sp<SkData> data = SkData::MakeFromStream(stream, restOfFile);
44
0
    SkReadBuffer readBuffer{data->data(), data->size()};
45
0
    readBuffer.setTypefaceArray(typefaceArray.data(), typefaceArray.size());
46
47
0
    while (!readBuffer.eof()) {
48
0
        SkTextBlobTrace::Record record;
49
0
        record.origUniqueID = readBuffer.readUInt();
50
0
        record.paint = readBuffer.readPaint();
51
0
        readBuffer.readPoint(&record.offset);
52
0
        record.blob = SkTextBlobPriv::MakeFromBuffer(readBuffer);
53
0
        trace.push_back(std::move(record));
54
0
    }
55
0
    return trace;
56
0
}
57
58
0
void SkTextBlobTrace::DumpTrace(const std::vector<SkTextBlobTrace::Record>& trace) {
59
0
    for (const SkTextBlobTrace::Record& record : trace) {
60
0
        const SkTextBlob* blob = record.blob.get();
61
0
        const SkPaint& p = record.paint;
62
0
        bool weirdPaint = p.getStyle() != SkPaint::kFill_Style
63
0
        || p.getMaskFilter() != nullptr
64
0
        || p.getPathEffect() != nullptr;
65
66
0
        SkDebugf("Blob %u ( %g %g ) %d\n  ",
67
0
                blob->uniqueID(), record.offset.x(), record.offset.y(), weirdPaint);
68
0
        SkTextBlobRunIterator iter(blob);
69
0
        int runNumber = 0;
70
0
        while (!iter.done()) {
71
0
            SkDebugf("Run %d\n    ", runNumber);
72
0
            SkFont font = iter.font();
73
0
            SkDebugf("Font %u %g %g %g %d %d %d\n    ",
74
0
                    font.getTypeface()->uniqueID(),
75
0
                    font.getSize(),
76
0
                    font.getScaleX(),
77
0
                    font.getSkewX(),
78
0
                    SkFontPriv::Flags(font),
79
0
                    (int)font.getEdging(),
80
0
                    (int)font.getHinting());
81
0
            uint32_t glyphCount = iter.glyphCount();
82
0
            const uint16_t* glyphs = iter.glyphs();
83
0
            for (uint32_t i = 0; i < glyphCount; i++) {
84
0
                SkDebugf("%02X ", glyphs[i]);
85
0
            }
86
0
            SkDebugf("\n");
87
0
            runNumber += 1;
88
0
            iter.next();
89
0
        }
90
0
    }
91
0
}
92
93
0
SkTextBlobTrace::Capture::Capture() : fTypefaceSet(new SkRefCntSet), fWriteBuffer({}) {
94
0
    fWriteBuffer.setTypefaceRecorder(fTypefaceSet);
95
0
}
96
97
0
SkTextBlobTrace::Capture::~Capture() = default;
98
99
void SkTextBlobTrace::Capture::capture(
100
0
        const sktext::GlyphRunList& glyphRunList, const SkPaint& paint) {
101
0
    const SkTextBlob* blob = glyphRunList.blob();
102
0
    if (blob != nullptr) {
103
0
        fWriteBuffer.writeUInt(blob->uniqueID());
104
0
        fWriteBuffer.writePaint(paint);
105
0
        fWriteBuffer.writePoint(glyphRunList.origin());
106
0
        SkTextBlobPriv::Flatten(*blob, fWriteBuffer);
107
0
        fBlobCount++;
108
0
    }
109
0
}
110
111
0
void SkTextBlobTrace::Capture::dump(SkWStream* dst) const {
112
0
    SkTLazy<SkFILEWStream> fileStream;
113
0
    if (!dst) {
114
0
        uint32_t id = SkChecksum::Mix(reinterpret_cast<uintptr_t>(this));
115
0
        SkString f = SkStringPrintf("diff-canvas-%08x-%04zu.trace", id, fBlobCount);
116
0
        dst = fileStream.init(f.c_str());
117
0
        if (!fileStream->isValid()) {
118
0
            SkDebugf("Error opening '%s'.\n", f.c_str());
119
0
            return;
120
0
        }
121
0
        SkDebugf("Saving trace to '%s'.\n", f.c_str());
122
0
    }
123
0
    SkASSERT(dst);
124
0
    int count = fTypefaceSet->count();
125
0
    dst->write32(count);
126
0
    SkPtrSet::Iter iter(*fTypefaceSet);
127
0
    while (void* ptr = iter.next()) {
128
0
        ((const SkTypeface*)ptr)->serialize(dst, SkTypeface::SerializeBehavior::kDoIncludeData);
129
0
    }
130
0
    dst->write32(fWriteBuffer.bytesWritten());
131
0
    fWriteBuffer.writeToStream(dst);
132
0
}
Unexecuted instantiation: SkTextBlobTrace::Capture::dump(SkWStream*) const
Unexecuted instantiation: SkTextBlobTrace::Capture::dump(SkWStream*) const