/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkPDFCatalog.h"
#include "SkPDFTypes.h"
#include "SkStream.h"
#ifdef SK_BUILD_FOR_WIN
#define SNPRINTF _snprintf
#else
#define SNPRINTF snprintf
#endif
///////////////////////////////////////////////////////////////////////////////
void SkPDFObject::emit(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
SkPDFObject* realObject = catalog->getSubstituteObject(this);
return realObject->emitObject(stream, catalog, indirect);
}
size_t SkPDFObject::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
SkDynamicMemoryWStream buffer;
emit(&buffer, catalog, indirect);
return buffer.getOffset();
}
void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) {}
void SkPDFObject::emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog) {
catalog->emitObjectNumber(stream, this);
stream->writeText(" obj\n");
emit(stream, catalog, false);
stream->writeText("\nendobj\n");
}
size_t SkPDFObject::getIndirectOutputSize(SkPDFCatalog* catalog) {
return catalog->getObjectNumberSize(this) + strlen(" obj\n") +
this->getOutputSize(catalog, false) + strlen("\nendobj\n");
}
void SkPDFObject::AddResourceHelper(SkPDFObject* resource,
SkTDArray<SkPDFObject*>* list) {
list->push(resource);
resource->ref();
}
void SkPDFObject::GetResourcesHelper(
const SkTDArray<SkPDFObject*>* resources,
const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) {
if (resources->count()) {
newResourceObjects->setReserve(
newResourceObjects->count() + resources->count());
for (int i = 0; i < resources->count(); i++) {
if (!knownResourceObjects.contains((*resources)[i]) &&
!newResourceObjects->contains((*resources)[i])) {
newResourceObjects->add((*resources)[i]);
(*resources)[i]->ref();
(*resources)[i]->getResources(knownResourceObjects,
newResourceObjects);
}
}
}
}
SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) {
SkSafeRef(obj);
}
SkPDFObjRef::~SkPDFObjRef() {}
void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
SkASSERT(!indirect);
catalog->emitObjectNumber(stream, fObj.get());
stream->writeText(" R");
}
size_t SkPDFObjRef::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
SkASSERT(!indirect);
return catalog->getObjectNumberSize(fObj.get()) + strlen(" R");
}
SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {}
SkPDFInt::~SkPDFInt() {}
void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
if (indirect) {
return emitIndirectObject(stream, catalog);
}
stream->writeDecAsText(fValue);
}
SkPDFBool::SkPDFBool(bool value) : fValue(value) {}
SkPDFBool::~SkPDFBool() {}
void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
SkASSERT(!indirect);
if (fValue) {
stream->writeText("true");
} else {
stream->writeText("false");
}
}
size_t SkPDFBool::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
SkASSERT(!indirect);
if (fValue) {
return strlen("true");
}
return strlen("false");
}
SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {}
SkPDFScalar::~SkPDFScalar() {}
void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
if (indirect) {
return emitIndirectObject(stream, catalog);
}
Append(fValue, stream);
}
// static
void SkPDFScalar::Append(SkScalar value, SkWStream* stream) {
// The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and
// +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31).
// When using floats that are outside the whole value range, we can use
// integers instead.
#if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
if (value > 32767 || value < -32767) {
stream->writeDecAsText(SkScalarRoundToInt(value));
return;
}
char buffer[SkStrAppendScalar_MaxSize];
char* end = SkStrAppendFixed(buffer, SkScalarToFixed(value));
stream->write(buffer, end - buffer);
return;
#endif // !SK_ALLOW_LARGE_PDF_SCALARS
#if defined(SK_ALLOW_LARGE_PDF_SCALARS)
// Floats have 24bits of significance, so anything outside that range is
// no more precise than an int. (Plus PDF doesn't support scientific
// notation, so this clamps to SK_Max/MinS32).
if (value > (1 << 24) || value < -(1 << 24)) {
stream->writeDecAsText(value);
return;
}
// Continue to enforce the PDF limits for small floats.
if (value < 1.0f/65536 && value > -1.0f/65536) {
stream->writeDecAsText(0);
return;
}
// SkStrAppendFloat might still use scientific notation, so use snprintf
// directly..
static const int kFloat_MaxSize = 19;
char buffer[kFloat_MaxSize];
int len = SNPRINTF(buffer, kFloat_MaxSize, "%#.8f", value);
// %f always prints trailing 0s, so strip them.
for (; buffer[len - 1] == '0' && len > 0; len--) {
buffer[len - 1] = '\0';
}
if (buffer[len - 1] == '.') {
buffer[len - 1] = '\0';
}
stream->writeText(buffer);
return;
#endif // SK_ALLOW_LARGE_PDF_SCALARS
}
SkPDFString::SkPDFString(const char value[])
: fValue(FormatString(value, strlen(value))) {
}
SkPDFString::SkPDFString(const SkString& value)
: fValue(FormatString(value.c_str(), value.size())) {
}
SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars)
: fValue(FormatString(value, len, wideChars)) {
}
SkPDFString::~SkPDFString() {}
void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
if (indirect)
return emitIndirectObject(stream, catalog);
stream->write(fValue.c_str(), fValue.size());
}
size_t SkPDFString::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
if (indirect)
return getIndirectOutputSize(catalog);
return fValue.size();
}
// static
SkString SkPDFString::FormatString(const char* input, size_t len) {
return DoFormatString(input, len, false, false);
}
SkString SkPDFString::FormatString(const uint16_t* input, size_t len,
bool wideChars) {
return DoFormatString(input, len, true, wideChars);
}
// static
SkString SkPDFString::DoFormatString(const void* input, size_t len,
bool wideInput, bool wideOutput) {
SkASSERT(len <= kMaxLen);
const uint16_t* win = (const uint16_t*) input;
const char* cin = (const char*) input;
if (wideOutput) {
SkASSERT(wideInput);
SkString result;
result.append("<");
for (size_t i = 0; i < len; i++) {
result.appendHex(win[i], 4);
}
result.append(">");
return result;
}
// 7-bit clean is a heuristic to decide what string format to use;
// a 7-bit clean string should require little escaping.
bool sevenBitClean = true;
for (size_t i = 0; i < len; i++) {
SkASSERT(!wideInput || !(win[i] & ~0xFF));
char val = wideInput ? win[i] : cin[i];
if (val > '~' || val < ' ') {
sevenBitClean = false;
break;
}
}
SkString result;
if (sevenBitClean) {
result.append("(");
for (size_t i = 0; i < len; i++) {
SkASSERT(!wideInput || !(win[i] & ~0xFF));
char
没有合适的资源?快使用搜索试试~ 我知道了~
l2tp.rar_flush
共5个文件
c:3个
h:2个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 70 浏览量
2022-09-24
20:47:36
上传
评论
收藏 9KB RAR 举报
温馨提示
TODO(chudy): Implement an optional flush button in Gui.
资源推荐
资源详情
资源评论
收起资源包目录
l2tp.rar (5个子文件)
SkGLWidget.c 3KB
SkPDFTypes.h 13KB
SkPDFTypes.c 14KB
l2tp.c 5KB
SkGLWidget.h 1KB
共 5 条
- 1
资源评论
我虽横行却不霸道
- 粉丝: 90
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功