19714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com/*
29714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * Copyright 2012 Google Inc.
39714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com *
49714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * Use of this source code is governed by a BSD-style license that can be
59714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * found in the LICENSE file.
69714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com */
79714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
89714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com#include "SkFontDescriptor.h"
99714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com#include "SkStream.h"
10d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman#include <SkData.h>
119714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
129714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.comenum {
133b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    // these must match the sfnt 'name' enums
149714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    kFontFamilyName = 0x01,
153b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    kFullName       = 0x04,
163b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    kPostscriptName = 0x06,
17d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
183b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    // These count backwards from 0xFF, so as not to collide with the SFNT
193b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    // defines for names in its 'name' table.
20d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    kFontIndex      = 0xFD,
213b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    kFontFileName   = 0xFE,
223b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    kSentinel       = 0xFF,
239714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com};
249714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
25d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanSkFontDescriptor::SkFontDescriptor(SkTypeface::Style style) : fFontIndex(0), fStyle(style) { }
269714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
273b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.comstatic void read_string(SkStream* stream, SkString* string) {
28a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org    const uint32_t length = SkToU32(stream->readPackedUInt());
299714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    if (length > 0) {
303b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com        string->resize(length);
313b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com        stream->read(string->writable_str(), length);
329714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    }
339714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com}
349714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
353b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.comstatic void write_string(SkWStream* stream, const SkString& string,
363b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                         uint32_t id) {
379714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    if (!string.isEmpty()) {
389714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com        stream->writePackedUInt(id);
399714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com        stream->writePackedUInt(string.size());
409714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com        stream->write(string.c_str(), string.size());
419714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    }
429714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com}
439714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
44d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanstatic size_t read_uint(SkStream* stream) {
45d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    return stream->readPackedUInt();
46d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman}
47d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman
48d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanstatic void write_uint(SkWStream* stream, size_t n, uint32_t id) {
49d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    stream->writePackedUInt(id);
50d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    stream->writePackedUInt(n);
51d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman}
52d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman
53d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanSkFontDescriptor::SkFontDescriptor(SkStream* stream) : fFontIndex(0) {
543b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    fStyle = (SkTypeface::Style)stream->readPackedUInt();
559714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
56d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    for (size_t id; (id = stream->readPackedUInt()) != kSentinel;) {
57d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        switch (id) {
583b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com            case kFontFamilyName:
593b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                read_string(stream, &fFamilyName);
603b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                break;
613b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com            case kFullName:
623b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                read_string(stream, &fFullName);
633b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                break;
643b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com            case kPostscriptName:
653b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                read_string(stream, &fPostscriptName);
663b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                break;
67d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman            case kFontIndex:
68d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman                fFontIndex = read_uint(stream);
69d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman                break;
703b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com            case kFontFileName:
713b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                read_string(stream, &fFontFileName);
723b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                break;
739714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com            default:
749714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com                SkDEBUGFAIL("Unknown id used by a font descriptor");
753b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com                return;
769714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com        }
779714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    }
78d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman
79d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    size_t length = stream->readPackedUInt();
80d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    if (length > 0) {
81d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        SkAutoTUnref<SkData> data(SkData::NewUninitialized(length));
82d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        if (stream->read(data->writable_data(), length) == length) {
83d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman            fFontData.reset(SkNEW_ARGS(SkMemoryStream, (data)));
84d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        }
85d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    }
869714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com}
879714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
889714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.comvoid SkFontDescriptor::serialize(SkWStream* stream) {
893b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    stream->writePackedUInt(fStyle);
909714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
913b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    write_string(stream, fFamilyName, kFontFamilyName);
923b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    write_string(stream, fFullName, kFullName);
933b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    write_string(stream, fPostscriptName, kPostscriptName);
943b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com    write_string(stream, fFontFileName, kFontFileName);
95d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    if (fFontIndex) {
96d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        write_uint(stream, fFontIndex, kFontIndex);
97d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    }
989714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com
999714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com    stream->writePackedUInt(kSentinel);
100d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman
101d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    if (fFontData) {
102d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        size_t length = fFontData->getLength();
103d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        stream->writePackedUInt(length);
104d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        stream->writeStream(fFontData, length);
105d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    } else {
106d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        stream->writePackedUInt(0);
107d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    }
1089714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com}
109