Información general de DWriteCore

DWriteCore es la implementación SDK de Aplicaciones para Windows de DirectWrite (DirectWrite es la API de DirectX para la representación de texto de alta calidad, fuentes de esquema independientes de resolución y compatibilidad completa con texto y diseño Unicode). DWriteCore es una forma de DirectWrite que se ejecuta en versiones de Windows hasta Windows 10, versión 1809 (10.0; Compilación 17763). DWriteCore implementa la misma API que DirectWrite, con algunas adiciones como se describe en este tema.

En este tema introductorio se describe qué es DWriteCore y se muestra cómo instalarlo en el entorno de desarrollo y el programa con él.

Para una aplicación que ya usa DirectWrite, cambiar a DWriteCore requiere cambios mínimos:

  • Agregue una referencia al paquete SDK de Aplicaciones para Windows.
  • Incluya dwrite_core.h en lugar de dwrite_3.h.
  • Vincular DWriteCore.lib en lugar de DWrite.lib.
  • Llame a DWriteCoreCreateFactory en lugar de DWriteCreateFactory.

A cambio, la aplicación obtiene las ventajas de SDK de Aplicaciones para Windows, es decir, el acceso a las API y funcionalidades más recientes, independientemente de la versión de Windows que ejecuta el cliente.

Sugerencia

Para obtener descripciones y vínculos a componentes de DirectX en desarrollo activo, consulte la entrada de blog Página de aterrizaje de DirectX.

Propuesta de valor de DWriteCore

DirectWrite admite una amplia gama de características que lo convierten en la herramienta de representación de fuentes que se elige en Windows para la mayoría de las aplicaciones, ya sea a través de llamadas directas o a través de Direct2D. DirectWrite incluye un sistema de diseño de texto independiente del dispositivo, representación de texto de Microsoft ClearType de alta calidad, texto acelerado por hardware, texto multiformato, características avanzadas de tipografía OpenType®, compatibilidad con lenguaje ancho y diseño y representación compatibles con GDI. DirectWrite ha estado disponible desde Windows Vista SP2 y ha evolucionado a lo largo de los años para incluir características más avanzadas, como fuentes de variables, que le permiten aplicar estilos, pesos y otros atributos a una fuente con un solo recurso de fuente.

Sin embargo, debido a la larga duración de DirectWrite, los avances en el desarrollo tienden a dejar atrás las versiones anteriores de Windows. Además, el estado de DirectWrite como tecnología de representación de texto premier solo está limitado a Windows, dejando que las aplicaciones multiplataforma escriban su propia pila de representación de texto o que se basen en soluciones de terceros.

DWriteCore resuelve los problemas fundamentales de la característica de versión huérfana y la compatibilidad multiplataforma mediante la eliminación de la biblioteca del sistema y el destino de todos los posibles puntos de conexión admitidos. Para ello, hemos integrado DWriteCore en SDK de Aplicaciones para Windows.

El valor principal que DWriteCore proporciona, como desarrollador, en SDK de Aplicaciones para Windows es que proporciona acceso a muchas (y finalmente todas) DirectWrite características. Todas las características de DWriteCore funcionarán igual en todas las versiones de nivel descendente sin ninguna disparidad con respecto a qué características podrían funcionar en qué versiones.

La aplicación de demostración DWriteCore: DWriteCoreGallery

DWriteCore se muestra por medio de la aplicación de ejemplo DWriteCoreGallery , que ahora está disponible para descargar y estudiar.

Introducción a DWriteCore

DWriteCore forma parte del SDK de Aplicaciones para Windows. En esta sección se describe cómo configurar el entorno de desarrollo para programar con DWriteCore.

Instalación de herramientas para el SDK de Aplicaciones para Windows

Consulte Instalación de herramientas para el SDK de Aplicaciones para Windows.

Creación de un nuevo proyecto

En Visual Studio, cree un nuevo proyecto a partir de la plantilla de proyecto Aplicación vacía empaquetada (WinUI 3 en escritorio). Para encontrar esa plantilla de proyecto, elija lenguaje: C++; platform: SDK de Aplicaciones para Windows; tipo de proyecto: Escritorio.

Para obtener más información, consulta Plantillas de proyecto para WinUI 3.

Instalación del paquete NuGet Microsoft.ProjectReunion.DWrite

En Visual Studio, haga clic en Project>Manage NuGet Packages... (Administrar paquetes NuGet).>Busque, escriba o pegue Microsoft.ProjectReunion.DWrite en el cuadro de búsqueda, seleccione el elemento en los resultados de la búsqueda y, a continuación, haga clic en Instalar para instalar el paquete para ese proyecto.

Como alternativa, comience con la aplicación de ejemplo DWriteCoreGallery.

Como alternativa, puede programar con DWriteCore empezando por el proyecto de aplicación de ejemplo DWriteCoreGallery y basar el desarrollo en ese proyecto. A continuación, puede quitar cualquier código fuente (o archivos) existente de ese proyecto de ejemplo y agregar cualquier nuevo código fuente (o archivos) al proyecto.

Uso de DWriteCore en el proyecto

Para obtener más información sobre la programación con DWriteCore, consulte la sección Programación con DWriteCore más adelante en este tema.

Las fases de lanzamiento de DWriteCore

Migrar DirectWrite a DWriteCore es un proyecto suficientemente grande para abarcar varios ciclos de versión de Windows. Ese proyecto se divide en fases, cada una de las cuales corresponde a un fragmento de funcionalidad que se entrega en una versión.

Características de la versión actual de DWriteCore

DWriteCore forma parte del SDK de Aplicaciones para Windows. Contiene las herramientas básicas que usted, como desarrollador, necesita consumir DWriteCore, incluidas las siguientes características.

Una característica de banner es fuentes de color. Las fuentes de color le permiten representar las fuentes con una funcionalidad de color más sofisticada más allá de colores simples. Por ejemplo, las fuentes de color son lo que potencia la capacidad de representar fuentes de iconos emoji y de barra de herramientas (por ejemplo, la última de las cuales usa Office). Las fuentes de color se introdujeron por primera vez en Windows 8.1, pero la característica se expandió en gran medida en Windows 10, versión 1607 (Actualización de aniversario).

El trabajo sobre la limpieza de la memoria caché de fuentes y el cargador de fuentes en memoria, permiten una carga más rápida de fuentes y mejoras en la memoria.

Con estas características, puede empezar inmediatamente a aprovechar algunas de las funcionalidades básicas modernas de DirectWrite, como las fuentes de variables. Las fuentes de variables son una de las características más importantes para DirectWrite clientes.

Nuestra invitación para usted como desarrollador de DirectWrite

DWriteCore, junto con otros componentes de SDK de Aplicaciones para Windows, se desarrollarán con apertura a los comentarios de los desarrolladores. Le invitamos a empezar a explorar DWriteCore y a proporcionar información o solicitudes en el desarrollo de características en nuestro repositorio de GitHub de SDK de Aplicaciones para Windows.

Programación con DWriteCore

Al igual que con DirectWrite, programa con DWriteCore a través de su API DE luz COM, a través de la interfaz IDWriteFactory.

Para usar DWriteCore, es necesario incluir el archivo de dwrite_core.h encabezado.

// pch.h
...
// DWriteCore header file.
#include <dwrite_core.h>

El dwrite_core.h archivo de encabezado define primero el token DWRITE_CORE y, a continuación, incluye el archivo de dwrite_3.h encabezado. El token de DWRITE_CORE es importante, ya que dirige los encabezados incluidos posteriormente para que todas las API de DirectWrite estén disponibles. Una vez que el proyecto haya incluido dwrite_core.h, puede continuar y escribir código, compilar y ejecutar.

API nuevas o diferentes para DWriteCore

La superficie de la API de DWriteCore es la misma que para DirectWrite. Pero hay un pequeño número de API nuevas que solo están en DWriteCore en el presente.

Creación de un objeto de fábrica

La función libre DWriteCoreCreateFactory crea un objeto factory que se usa para la creación posterior de objetos DWriteCore individuales.

DWriteCoreCreateFactory es funcionalmente igual que la función DWriteCreateFactory exportada por la versión del sistema de DirectWrite. La función DWriteCore tiene un nombre diferente para evitar ambigüedad.

Creación de un objeto de fábrica restringido

La enumeración DWRITE_FACTORY_TYPE tiene una constante nueva, DWRITE_FACTORY_TYPE_ISOLATED2, que indica un generador restringido. Una fábrica restringida está más bloqueada que una fábrica aislada. No interactúa con un proceso cruzado ni una caché de fuentes persistente de ninguna manera. Además, la colección de fuentes del sistema devuelta de esta fábrica incluye solo fuentes conocidas. Aquí se muestra cómo puede usar DWRITE_FACTORY_TYPE_ISOLATED2 para crear un objeto de fábrica restringido al llamar a la función gratuita DWriteCoreCreateFactory .

// Create a factory that doesn't interact with any cross-process nor
// persistent cache state.
winrt::com_ptr<::IDWriteFactory7> spFactory;
winrt::check_hresult(
  ::DWriteCoreCreateFactory(
    DWRITE_FACTORY_TYPE_ISOLATED2,
    __uuidof(spFactory),
    reinterpret_cast<IUnknown**>(spFactory.put())
  )
);

Si pasa DWRITE_FACTORY_TYPE_ISOLATED2 a una versión anterior de DirectWrite que no la admite, DWriteCreateFactory devuelve E_INVALIDARG.

Dibujar glifos en un mapa de bits de memoria del sistema

DirectWrite tiene una interfaz de destino de representación de mapa de bits que admite la representación de glifos en un mapa de bits en la memoria del sistema. Sin embargo, actualmente la única manera de obtener acceso a los datos de píxeles subyacentes es pasar por GDI, por lo que la API no se puede usar entre plataformas. Esto se soluciona fácilmente agregando un método para recuperar los datos de píxeles.

Además, DWriteCore presenta la interfaz IDWriteBitmapRenderTarget2 y su método IDWriteBitmapRenderTarget2::GetBitmapData. Ese método toma un parámetro de tipo (puntero a) DWRITE_BITMAP_DATA_BGRA32, que es una nueva estructura.

La aplicación crea un destino de representación de mapa de bits llamando a IDWriteGdiInterop::CreateBitmapRenderTarget. En Windows, un destino de representación de mapa de bits encapsula un controlador de dominio de memoria GDI con un mapa de bits independiente del dispositivo GDI (DIB) seleccionado en él. IDWriteBitmapRenderTarget::D rawGlyphRun representa glifos en la DIB. DirectWrite representa los glifos sin pasar por GDI. Después, la aplicación puede obtener la HDC del destino de representación del mapa de bits y usar BitBlt para copiar los píxeles en una ventana HDC.

En plataformas que no son windows, la aplicación todavía puede crear un destino de representación de mapa de bits, pero simplemente encapsula una matriz de memoria del sistema sin HDC ni DIB. Sin una HDC, debe haber otra manera de que la aplicación obtenga los píxeles de mapa de bits para que pueda copiarlos o usarlos de otro modo. Incluso en Windows, a veces resulta útil obtener los datos de píxeles reales y se muestra la forma actual de hacerlo en el ejemplo de código siguiente.

// pch.h
#pragma once

#include <windows.h>
#include <Unknwn.h>
#include <winrt/Windows.Foundation.h>

// WinMain.cpp
#include "pch.h"
#include <dwrite_core.h>
#pragma comment(lib, "Gdi32")

class TextRenderer
{
    DWRITE_BITMAP_DATA_BGRA32 m_targetBitmapData;

public:
    void InitializeBitmapData(winrt::com_ptr<IDWriteBitmapRenderTarget> const& renderTarget)
    {
        // Query the bitmap render target for the new interface. 
        winrt::com_ptr<IDWriteBitmapRenderTarget2> renderTarget2;
        renderTarget2 = renderTarget.try_as<IDWriteBitmapRenderTarget2>();

        if (renderTarget2)
        {
            // IDWriteBitmapRenderTarget2 exists, so we can get the bitmap the easy way. 
            winrt::check_hresult(renderTarget2->GetBitmapData(OUT & m_targetBitmapData));
        }
        else
        {
            // We're using an older version that doesn't implement IDWriteBitmapRenderTarget2, 
            // so we have to get the bitmap by going through GDI. First get the bitmap handle. 
            HDC hdc = renderTarget->GetMemoryDC();
            winrt::handle dibHandle{ GetCurrentObject(hdc, OBJ_BITMAP) };
            winrt::check_bool(bool{ dibHandle });

            // Call a GDI function to fill in the DIBSECTION structure for the bitmap. 
            DIBSECTION dib;
            winrt::check_bool(GetObject(dibHandle.get(), sizeof(dib), &dib));

            m_targetBitmapData.width = dib.dsBm.bmWidth;
            m_targetBitmapData.height = dib.dsBm.bmHeight;
            m_targetBitmapData.pixels = static_cast<uint32_t*>(dib.dsBm.bmBits);
        }
    }
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
    TextRenderer textRenderer;
    winrt::com_ptr<IDWriteBitmapRenderTarget> renderTarget{ /* ... */ };
    textRenderer.InitializeBitmapData(renderTarget);
}

Otras diferencias de API entre DWriteCore y DirectWrite

Hay algunas API que solo son códigos auxiliares o se comportan de forma algo diferente en plataformas que no son de Windows. Por ejemplo, IDWriteGdiInterop::CreateFontFaceFromHdc devuelve E_NOTIMPL en plataformas que no son windows, ya que no hay nada como un HDC sin GDI.

Y, por último, hay otras API de Windows que normalmente se usan junto con DirectWrite (Direct2D es un ejemplo notable). Sin embargo, actualmente, Direct2D y DWriteCore no interoperan. Por ejemplo, si crea un IDWriteTextLayout mediante DWriteCore y lo pasa a D2D1RenderTarget::D rawTextLayout, se producirá un error en esa llamada.