Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/gfx/skia/skia/src/utils/win/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  SkDWriteFontFileStream.cpp   Sprache: C

 
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTypes.h"
#if defined(SK_BUILD_FOR_WIN)

#include "include/core/SkTypes.h"
#include "include/private/base/SkTFitsIn.h"
#include "include/private/base/SkTemplates.h"
#include "src/utils/win/SkDWriteFontFileStream.h"
#include "src/utils/win/SkHRESULT.h"
#include "src/utils/win/SkTScopedComPtr.h"

#include <dwrite.h>

using namespace skia_private;

///////////////////////////////////////////////////////////////////////////////
//  SkIDWriteFontFileStream

SkDWriteFontFileStream::SkDWriteFontFileStream(IDWriteFontFileStream* fontFileStream)
    : fFontFileStream(SkRefComPtr(fontFileStream))
    , fPos(0)
    , fLockedMemory(nullptr)
    , fFragmentLock(nullptr) {
}

SkDWriteFontFileStream::~SkDWriteFontFileStream() {
    if (fFragmentLock) {
        fFontFileStream->ReleaseFileFragment(fFragmentLock);
    }
}

size_t SkDWriteFontFileStream::read(void* buffer, size_t size) {
    HRESULT hr = S_OK;

    if (nullptr == buffer) {
        size_t fileSize = this->getLength();

        if (fPos + size > fileSize) {
            size_t skipped = fileSize - fPos;
            fPos = fileSize;
            return skipped;
        } else {
            fPos += size;
            return size;
        }
    }

    const void* start;
    void* fragmentLock;
    hr = fFontFileStream->ReadFileFragment(&start, fPos, size, &fragmentLock);
    if (SUCCEEDED(hr)) {
        memcpy(buffer, start, size);
        fFontFileStream->ReleaseFileFragment(fragmentLock);
        fPos += size;
        return size;
    }

    //The read may have failed because we asked for too much data.
    size_t fileSize = this->getLength();
    if (fPos + size <= fileSize) {
        //This means we were within bounds, but failed for some other reason.
        return 0;
    }

    size_t read = fileSize - fPos;
    hr = fFontFileStream->ReadFileFragment(&start, fPos, read, &fragmentLock);
    if (SUCCEEDED(hr)) {
        memcpy(buffer, start, read);
        fFontFileStream->ReleaseFileFragment(fragmentLock);
        fPos = fileSize;
        return read;
    }

    return 0;
}

bool SkDWriteFontFileStream::isAtEnd() const {
    return fPos == this->getLength();
}

bool SkDWriteFontFileStream::rewind() {
    fPos = 0;
    return true;
}

SkDWriteFontFileStream* SkDWriteFontFileStream::onDuplicate() const {
    return new SkDWriteFontFileStream(fFontFileStream.get());
}

size_t SkDWriteFontFileStream::getPosition() const {
    return fPos;
}

bool SkDWriteFontFileStream::seek(size_t position) {
    size_t length = this->getLength();
    fPos = (position > length) ? length : position;
    return true;
}

bool SkDWriteFontFileStream::move(long offset) {
    return seek(fPos + offset);
}

SkDWriteFontFileStream* SkDWriteFontFileStream::onFork() const {
    std::unique_ptr<SkDWriteFontFileStream> that(this->duplicate());
    that->seek(fPos);
    return that.release();
}

size_t SkDWriteFontFileStream::getLength() const {
    UINT64 realFileSize = 0;
    fFontFileStream->GetFileSize(&realFileSize);
    if (!SkTFitsIn<size_t>(realFileSize)) {
        return 0;
    }
    return static_cast<size_t>(realFileSize);
}

const void* SkDWriteFontFileStream::getMemoryBase() {
    if (fLockedMemory) {
        return fLockedMemory;
    }

    UINT64 fileSize;
    HRNM(fFontFileStream->GetFileSize(&fileSize), "Could not get file size");
    HRNM(fFontFileStream->ReadFileFragment(&fLockedMemory, 0, fileSize, &fFragmentLock),
         "Could not lock file fragment.");
    return fLockedMemory;
}

///////////////////////////////////////////////////////////////////////////////
//  SkIDWriteFontFileStreamWrapper

HRESULT SkDWriteFontFileStreamWrapper::Create(SkStreamAsset* stream,
                                              SkDWriteFontFileStreamWrapper** streamFontFileStream)
{
    *streamFontFileStream = new SkDWriteFontFileStreamWrapper(stream);
    if (nullptr == *streamFontFileStream) {
        return E_OUTOFMEMORY;
    }
    return S_OK;
}

SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStreamAsset* stream)
    : fRefCount(1), fStream(stream) {
}

SK_STDMETHODIMP SkDWriteFontFileStreamWrapper::QueryInterface(REFIID iid, void** ppvObject) {
    if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
        *ppvObject = this;
        AddRef();
        return S_OK;
    } else {
        *ppvObject = nullptr;
        return E_NOINTERFACE;
    }
}

SK_STDMETHODIMP_(ULONG) SkDWriteFontFileStreamWrapper::AddRef() {
    return InterlockedIncrement(&fRefCount);
}

SK_STDMETHODIMP_(ULONG) SkDWriteFontFileStreamWrapper::Release() {
    ULONG newCount = InterlockedDecrement(&fRefCount);
    if (0 == newCount) {
        delete this;
    }
    return newCount;
}

SK_STDMETHODIMP SkDWriteFontFileStreamWrapper::ReadFileFragment(
    void const** fragmentStart,
    UINT64 fileOffset,
    UINT64 fragmentSize,
    void** fragmentContext)
{
    // The loader is responsible for doing a bounds check.
    UINT64 fileSize;
    this->GetFileSize(&fileSize);
    if (fileOffset > fileSize || fragmentSize > fileSize - fileOffset) {
        *fragmentStart = nullptr;
        *fragmentContext = nullptr;
        return E_FAIL;
    }

    if (!SkTFitsIn<size_t>(fileOffset + fragmentSize)) {
        return E_FAIL;
    }

    const void* data = fStream->getMemoryBase();
    if (data) {
        *fragmentStart = static_cast<BYTE const*>(data) + static_cast<size_t>(fileOffset);
        *fragmentContext = nullptr;

    } else {
        // May be called from multiple threads.
        SkAutoMutexExclusive ama(fStreamMutex);

        *fragmentStart = nullptr;
        *fragmentContext = nullptr;

        if (!fStream->seek(static_cast<size_t>(fileOffset))) {
            return E_FAIL;
        }
        AutoTMalloc<uint8_t> streamData(static_cast<size_t>(fragmentSize));
        if (fStream->read(streamData.get(), static_cast<size_t>(fragmentSize)) != fragmentSize) {
            return E_FAIL;
        }

        *fragmentStart = streamData.get();
        *fragmentContext = streamData.release();
    }
    return S_OK;
}

SK_STDMETHODIMP_(void) SkDWriteFontFileStreamWrapper::ReleaseFileFragment(void* fragmentContext) {
    sk_free(fragmentContext);
}

SK_STDMETHODIMP SkDWriteFontFileStreamWrapper::GetFileSize(UINT64* fileSize) {
    *fileSize = fStream->getLength();
    return S_OK;
}

SK_STDMETHODIMP SkDWriteFontFileStreamWrapper::GetLastWriteTime(UINT64* lastWriteTime) {
    // The concept of last write time does not apply to this loader.
    *lastWriteTime = 0;
    return E_NOTIMPL;
}

#endif//defined(SK_BUILD_FOR_WIN)

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.