/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkRemoteGlyphCache.h"
struct WireTypeface {
// std::thread::id thread_id; // TODO:need to figure a good solution
SkFontID typeface_id;
SkFontStyle style;
bool is_fixed;
};
void SkRemoteGlyphCacheRenderer::prepareSerializeProcs(SkSerialProcs* procs) {
auto encode = [](SkTypeface* tf, void* ctx) {
return reinterpret_cast<SkRemoteGlyphCacheRenderer*>(ctx)->encodeTypeface(tf);
};
procs->fTypefaceProc = encode;
procs->fTypefaceCtx = this;
}
SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext(
const SkScalerContextRecDescriptor& desc, SkFontID typefaceId)
{
auto scaler = fScalerContextMap.find(desc);
if (scaler == nullptr) {
auto typefaceIter = fTypefaceMap.find(typefaceId);
if (typefaceIter == nullptr) {
// TODO: handle this with some future fallback strategy.
SK_ABORT("unknown type face");
// Should never happen
return nullptr;
}
auto tf = typefaceIter->get();
SkScalerContextEffects effects;
auto mapSc = tf->createScalerContext(effects, &desc.desc(), false);
scaler = fScalerContextMap.set(desc, std::move(mapSc));
}
return scaler->get();
}
sk_sp<SkData> SkRemoteGlyphCacheRenderer::encodeTypeface(SkTypeface* tf) {
WireTypeface wire = {
SkTypeface::UniqueID(tf),
tf->fontStyle(),
tf->isFixedPitch()
};
auto typeFace = fTypefaceMap.find(SkTypeface::UniqueID(tf));
if (typeFace == nullptr) {
fTypefaceMap.set(SkTypeface::UniqueID(tf), sk_ref_sp(tf));
}
// Can this be done with no copy?
return SkData::MakeWithCopy(&wire, sizeof(wire));
}
SkRemoteGlyphCacheGPU::SkRemoteGlyphCacheGPU(
std::unique_ptr<SkRemoteScalerContext> remoteScalerContext)
: fRemoteScalerContext{std::move(remoteScalerContext)} { }
void SkRemoteGlyphCacheGPU::prepareDeserializeProcs(SkDeserialProcs* procs) {
auto decode = [](const void* buf, size_t len, void* ctx) {
return reinterpret_cast<SkRemoteGlyphCacheGPU*>(ctx)->decodeTypeface(buf, len);
};
procs->fTypefaceProc = decode;
procs->fTypefaceCtx = this;
}
sk_sp<SkTypeface> SkRemoteGlyphCacheGPU::decodeTypeface(const void* buf, size_t len) {
WireTypeface wire;
if (len < sizeof(wire)) {
SK_ABORT("Incomplete transfer");
return nullptr;
}
memcpy(&wire, buf, sizeof(wire));
auto typeFace = fMapIdToTypeface.find(wire.typeface_id);
if (typeFace == nullptr) {
auto newTypeface = sk_make_sp<SkTypefaceProxy>(
wire.typeface_id,
wire.style,
wire.is_fixed,
fRemoteScalerContext.get());
typeFace = fMapIdToTypeface.set(wire.typeface_id, newTypeface);
}
return *typeFace;
}