自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

操作實(shí)例:閱讀器應(yīng)用(DirectX 和 XAML)

開發(fā) 前端
下面我們介紹如何使用 DirectX、C++ 和 XAML 創(chuàng)建豐富的文檔閱讀器應(yīng)用。我們涵蓋了此類型應(yīng)用的結(jié)構(gòu)、技術(shù)和最佳實(shí)踐,包括如何使用 Virtual Surface Image Source 在 DirectX 繪圖代碼和 XAML 界面管理之間進(jìn)行交互操作,使用 DirectWrite 加載字體,使用 WIC 加載圖像,以及將 Direct2D 圖像效果應(yīng)用到圖像。

隨著平板電腦變得越來越普及,融合了閱讀體驗(yàn)的應(yīng)用很快就會變得流行起來。 下面我們介紹如何使用 DirectX、C++ 和 XAML 創(chuàng)建豐富的文檔閱讀器應(yīng)用。我們涵蓋了此類型應(yīng)用的結(jié)構(gòu)、技術(shù)和***實(shí)踐,包括如何使用 Virtual Surface Image Source 在 DirectX 繪圖代碼和 XAML 界面管理之間進(jìn)行交互操作,使用 DirectWrite 加載字體,使用 WIC 加載圖像,以及將 Direct2D 圖像效果應(yīng)用到圖像。

我們將了解使用 XAML 互操作的 DirectX 雜志應(yīng)用示例的大量代碼并探討構(gòu)成應(yīng)用的不同組件。

雜志示例結(jié)構(gòu)

示例中的文件分為三組:XML、XAML 和 DirectX。XML 組中的文件負(fù)責(zé)表示 XML 文件(容納有關(guān)文章的所有信息)中的每個標(biāo)記。XAML 組中的文件負(fù)責(zé)設(shè)置 XAML 元素并與Virtual Surface Image Source協(xié)作。***,DirectX 組中的文件負(fù)責(zé)像 DirectWrite 自定義字體加載、Direct2D 圖像效果和 WIC 圖像解碼這樣的事情。

名稱 類型
BindableProperty XAML
ContentImageSource XAML
Design XML
Document XML
Element XML
FontFileStream DirectX
FontLoader DirectX
Image XML
ImageFile XML
ImageFrame XML
Layer XML
List XML
Page XML
PageModel XAML
PageRoll XML
Rectangle XML
Resource XML
Story XML
Text XML
TextFrame XML
TreeIterator XML

 

虛擬圖面圖像源

Virtual Surface Image Source (VSIS)是一個 XAML 管理的呈現(xiàn)圖面,當(dāng)你要編寫一個涉及平移和縮放的應(yīng)用時,它將非常有用。此圖面與 DirectX 中的任何其他位圖源相同,除了 XAML 管理 DirectX 和圖像源之間的交互操作這一事實(shí)。

當(dāng)你希望在應(yīng)用中使用 VSIS 時,你必須:

  • 確定內(nèi)容的大小。
  • 創(chuàng)建圖像大小的 VSIS。
  • 將 DXGI 設(shè)備設(shè)置為 VSIS 上的設(shè)備。
  • 注冊圖像源回調(diào),以便當(dāng)你需要呈現(xiàn)內(nèi)容時收到消息。

下面的代碼顯示如何執(zhí)行這些步驟。

  1. // Measure the content and store its size. 
  2.     Measure(&m_contentSize); 
  3.  
  4.     // Create an image source at the initial pixel size. 
  5.     m_imageSource = ref new VirtualSurfaceImageSource(m_contentSize.cx, m_contentSize.cy); 
  6.  
  7.     ComPtr<IUnknown> unknown(reinterpret_cast<IUnknown*>(m_imageSource)); 
  8.     unknown.As(&m_imageSourceNative); 
  9.  
  10.     auto renderer = m_document->GetRenderer(); 
  11.  
  12.     // Set DXGI device to the image source 
  13.     ComPtr<IDXGIDevice> dxgiDevice; 
  14.     renderer->GetDXGIDevice(&dxgiDevice); 
  15.     m_imageSourceNative->SetDevice(dxgiDevice.Get()); 
  16.  
  17.     // Register image source's update callback so update can be made to it. 
  18.     m_imageSourceNative->RegisterForUpdatesNeeded(this); 

選擇,你有了一個 VSIS 并注冊你的類接收來自虛擬圖面的回調(diào)信息。接下來,你必須實(shí)現(xiàn)當(dāng)你需要更新內(nèi)容時 VSIS 調(diào)用的回調(diào)方法。

當(dāng)用戶通過滾動內(nèi)容來操作 VSIS 時,VSIS 將調(diào)用你注冊的類的 UpdatesNeeded 方法。因此,你必須實(shí)現(xiàn) UpdatesNeeded 回調(diào)方法。

下面的代碼向你顯示了如何實(shí)現(xiàn) UpdatesNeeded 回調(diào)方法和 Draw 幫助程序方法。當(dāng) VSISContentImageSource 類上調(diào)用此回調(diào)方法時,此方法將檢索 VSIS 正在使用 VSISGetUpdateRectCount 方法呈現(xiàn)的更新的矩形。然后,你對此更新的區(qū)域調(diào)用繪制方法。

  1. / This method is called when the framework needs to update region managed by 
  2. // the virtual surface image source. 
  3. HRESULT STDMETHODCALLTYPE ContentImageSource::UpdatesNeeded() 
  4.     HRESULT hr = S_OK; 
  5.  
  6.     try 
  7.     { 
  8.         ULONG drawingBoundsCount = 0; 
  9.  
  10.         DX::ThrowIfFailed( 
  11.             m_imageSourceNative->GetUpdateRectCount(&drawingBoundsCount) 
  12.             ); 
  13.  
  14.         std::unique_ptr<RECT[]> drawingBounds(new RECT[drawingBoundsCount]); 
  15.  
  16.         DX::ThrowIfFailed( 
  17.             m_imageSourceNative->GetUpdateRects(drawingBounds.get(), drawingBoundsCount) 
  18.             ); 
  19.  
  20.         // This code doesn't try to coalesce multiple drawing bounds into one. Although that 
  21.         // extra process  reduces the number of draw calls, it requires the virtual surface 
  22.         // image source to manage non-uniform tile size, which requires it to make extra copy 
  23.         // operations to the compositor. By using the drawing bounds it directly returns, which are 
  24.         //  non-overlapping  tiles of the same size, the compositor can use these tiles directly, 
  25.         // which can greatly reduce the amount of memory needed by the virtual surface image source. 
  26.         // This results in more draw calls, but Direct2D can accommodate them 
  27.         // without significant impact on presentation frame rate. 
  28.         for (ULONG i = 0; i < drawingBoundsCount; ++i) 
  29.         { 
  30.             if (Draw(drawingBounds[i])) 
  31.             { 
  32.                 // Drawing isn't complete. This can happen when the content is still being 
  33.                 // asynchronously loaded. Inform the image source to invalidate the drawing 
  34.                 // bounds so that it calls back to redraw. 
  35.                 DX::ThrowIfFailed( 
  36.                     m_imageSourceNative->Invalidate(drawingBounds[i]) 
  37.                     ); 
  38.             } 
  39.         } 
  40.     } 
  41.     catch (Platform::Exception^ exception) 
  42.     { 
  43.         hr = exception->HResult; 
  44.     } 
  45.  
  46.     return hr; 
  47.  
  48. bool ContentImageSource::Draw(RECT const& drawingBounds) 
  49.     ComPtr<IDXGISurface> dxgiSurface; 
  50.     POINT surfaceOffset = {0}; 
  51.  
  52.     DX::ThrowIfFailed( 
  53.         m_imageSourceNative->BeginDraw( 
  54.             drawingBounds, 
  55.             &dxgiSurface, 
  56.             &surfaceOffset 
  57.             ) 
  58.         ); 
  59.  
  60.     auto renderer = m_document->GetRenderer(); 
  61.  
  62.     ComPtr<ID2D1DeviceContext> d2dDeviceContext; 
  63.     renderer->GetD2DDeviceContext(&d2dDeviceContext); 
  64.  
  65.     ComPtr<ID2D1Bitmap1> bitmap; 
  66.     DX::ThrowIfFailed( 
  67.         d2dDeviceContext->CreateBitmapFromDxgiSurface( 
  68.             dxgiSurface.Get(), 
  69.             nullptr, 
  70.             &bitmap 
  71.             ) 
  72.         ); 
  73.  
  74.     // Begin the drawing batch 
  75.     d2dDeviceContext->BeginDraw(); 
  76.  
  77.     // Scale content design coordinate to the display coordinate, 
  78.     // then translate the drawing to the designated place on the surface. 
  79.     D2D1::Matrix3x2F transform = 
  80.         D2D1::Matrix3x2F::Scale( 
  81.             m_document->DesignToDisplayWidth(1.0f), 
  82.             m_document->DesignToDisplayHeight(1.0f) 
  83.             ) * 
  84.         D2D1::Matrix3x2F::Translation( 
  85.             static_cast<float>(surfaceOffset.x - drawingBounds.left), 
  86.             static_cast<float>(surfaceOffset.y - drawingBounds.top) 
  87.             ); 
  88.  
  89.     // Prepare to draw content. This is the appropriate time for content element 
  90.     // to draw to an intermediate if there is any. It is important for performance 
  91.     // reason that you don't call SetTarget too often. Preparing the intermediates 
  92.     // upfront reduces the number of times the render target switches back and forth. 
  93.     bool needRedraw = m_content->PrepareToDraw( 
  94.         m_document, 
  95.         transform 
  96.         ); 
  97.  
  98.     if (!needRedraw) 
  99.     { 
  100.         // Set the render target to surface given by the framework 
  101.         d2dDeviceContext->SetTarget(bitmap.Get()); 
  102.  
  103.         d2dDeviceContext->SetTransform(D2D1::IdentityMatrix()); 
  104.  
  105.         // Constrain the drawing to the designated portion of the surface 
  106.         d2dDeviceContext->PushAxisAlignedClip( 
  107.             D2D1::RectF( 
  108.                 static_cast<float>(surfaceOffset.x), 
  109.                 static_cast<float>(surfaceOffset.y), 
  110.                 static_cast<float>(surfaceOffset.x + (drawingBounds.right - drawingBounds.left)), 
  111.                 static_cast<float>(surfaceOffset.y + (drawingBounds.bottom - drawingBounds.top)) 
  112.                 ), 
  113.             D2D1_ANTIALIAS_MODE_ALIASED 
  114.             ); 
  115.  
  116.         // The Clear call must follow the PushAxisAlignedClip call. 
  117.         // Placing the Clear call before the clip is set violates the contract of the 
  118.         // virtual surface image source in that the app draws outside the 
  119.         // designated portion of the surface the image source hands over to it. This 
  120.         // violation won't actually cause the content to spill outside the designated 
  121.         // area because the image source will safeguard it. But this extra protection 
  122.         // has a runtime cost associated with it, and in some drivers this cost can be 
  123.         // very expensive. So the best performance strategy here is to never create a 
  124.         // situation where this protection is required. Not drawing outside the appropriate 
  125.         // clip does that the right way. 
  126.         d2dDeviceContext->Clear(D2D1::ColorF(0, 0)); 
  127.  
  128.         // Draw the content 
  129.         needRedraw = m_content->Draw( 
  130.             m_document, 
  131.             transform 
  132.             ); 
  133.  
  134.         d2dDeviceContext->PopAxisAlignedClip(); 
  135.  
  136.         d2dDeviceContext->SetTarget(nullptr); 
  137.     } 
  138.  
  139.     // End the drawing 
  140.     DX::ThrowIfFailed( 
  141.         d2dDeviceContext->EndDraw() 
  142.         ); 
  143.  
  144.     // Submit the completed drawing to the framework 
  145.     DX::ThrowIfFailed( 
  146.         m_imageSourceNative->EndDraw() 
  147.         ); 
  148.  
  149.     return needRedraw; 

#p#

實(shí)現(xiàn)回調(diào)后,你的應(yīng)用現(xiàn)在將從 VSIS 接收有關(guān)你需要繪制的區(qū)域的信息。你的 draw 函數(shù)只需要獲取此矩形,并繪制到 VSIS 的右側(cè)區(qū)域中。通過實(shí)現(xiàn)這兩個回調(diào),并向 VSIS 注冊類,應(yīng)用便可以在用戶操作內(nèi)容時呈現(xiàn)到虛擬圖面并更新必要的區(qū)域,以顯示更多圖面。

使用 XML 加載內(nèi)容和綁定數(shù)據(jù)

我們的應(yīng)用顯示在雜志中的信息都存儲在 Sample.story 文件中。此文件是一個 XML 文檔,它包含有關(guān)文章內(nèi)容、標(biāo)題、字體、背景圖像和其他屬性的信息。 應(yīng)用需要編入摘要的每一部分重要信息都有一個標(biāo)記。通過使用標(biāo)記,你可以輕松地展開文章,從該標(biāo)記的信息中創(chuàng)建對象,以及將該數(shù)據(jù)綁定到你的應(yīng)用的 XAML 中。

因?yàn)?.story 文件中的信息采用自定義的 XML 架構(gòu),所以 TreeIterator.h 中的類幫助分析此 XML 數(shù)據(jù)并將其置于應(yīng)用的專用類中。

下面是應(yīng)用使用的 .story 文件中包含的信息示例。

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <story> 
  3.     <resource> 
  4.         <image name="grasshopper-image" file="grasshopper.jpg"/> 
  5.         <image name="butterfly-image" file="butterfly.jpg"/> 
  6.         <text name="section" font-family="Arial" font-stretch="2" font-size="22">A BUG'S LIFE</text> 
  7.         <text name="grasshopper-title" font-family="Gill Sans" font-stretch="3" font-weight="700" font-size="70">GRASSHOPPER</text> 
  8.         <text name="grasshopper-quote" font-family="Pericles" font-size="18">a slender plant-eating flying and jumping insect that produces a buzzing sound by rubbing its back legs against its forewings</text> 
  9.         <text name="grasshopper-body" font-family="Kootenay" font-size="16"><bold>LOREM</bold> ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. 
  10. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem.</text> 

如 XML 代碼段所示,信息的標(biāo)記直接對應(yīng)于應(yīng)用中的某些 XML 類。當(dāng)?shù)鞣治?XML 文件時,將為每個標(biāo)記創(chuàng)建一個相同名稱的類,在其中存儲標(biāo)記中的信息。

在我們將 XML 文件中的所有信息都存儲到應(yīng)用后,你將該數(shù)據(jù)綁定到 UI 上的元素。此數(shù)據(jù)綁定存在于兩個位置,頁面的 XAML 標(biāo)記中及 XAML 標(biāo)記頁面隨附的 cpp 文件中。在此示例中,它存在于 MainPage.xamlMainPage.cpp 中。

在 XAML 標(biāo)記中創(chuàng)建 FlipView、DataTemplateScrollViewer 類的實(shí)例。然后,將該信息綁定到那些 XAML 標(biāo)記項。下面是這些元素的 XAML 標(biāo)記代碼。

  1. <FlipView x:Name="FlipView" ManipulationMode="TranslateInertia"> 
  2.         <FlipView.ItemTemplate> 
  3.             <DataTemplate> 
  4.                 <ScrollViewer ZoomMode="Disabled" VerticalScrollMode="Enabled" IsVerticalRailEnabled="True"> 
  5.                     <ScrollViewer.Background> 
  6.                         <ImageBrush ImageSource="{Binding Background}"/> 
  7.                     </ScrollViewer.Background> 
  8.                     <Image  
  9.                         Source="{Binding Content}"  
  10.                         Width="{Binding ContentWidth}"  
  11.                         Height="{Binding ContentHeight}"  
  12.                         HorizontalAlignment="Left" 
  13.                         /> 
  14.                 </ScrollViewer> 
  15.             </DataTemplate> 
  16.         </FlipView.ItemTemplate> 
  17.     </FlipView> 

此處的代碼顯示,背景和圖像全都具有對應(yīng)于 XML 源中數(shù)據(jù)的數(shù)據(jù)綁定?,F(xiàn)在,你需要使用你具有的信息填充這些綁定。你將代碼放置在相同名稱的 cpp 文件中。下面是 MainPage.cpp 中幫助進(jìn)行數(shù)據(jù)綁定的代碼。

  1. void MainPage::DocumentLoaded(_In_ Document^ document) 
  2.     // Parse the document into an element tree. 
  3.     document->Parse(); 
  4.  
  5.     auto contentRoot = document->GetContentRoot(); 
  6.  
  7.     if (contentRoot != nullptr) 
  8.     { 
  9.         // Create a collection of content element to bind to the view 
  10.         auto items = ref new Platform::Collections::Vector<Platform::Object^>(); 
  11.  
  12.         auto pageContent = contentRoot->GetFirstChild(); 
  13.  
  14.         while (pageContent != nullptr) 
  15.         { 
  16.             items->Append(ref new PageModel(pageContent, document)); 
  17.  
  18.             pageContent = pageContent->GetNextSibling(); 
  19.         } 
  20.  
  21.         FlipView->ItemsSource = items; 
  22.  
  23.         // Load the saved document state if any 
  24.         LoadState(ApplicationData::Current->LocalSettings->Values); 
  25.  
  26.         m_document = document; 
  27.     } 

此處的代碼分析 XML 文檔,然后創(chuàng)建內(nèi)容元素的矢量,以便將其綁定到 UI 中的 XAML 元素。

自定義字體加載

要在此 DirectX 應(yīng)用中使用自定義字體,你必須在 DirectWrite 中實(shí)現(xiàn)異步字體加載程序和集合。在 DirectX 應(yīng)用中,如果你希望提供一個要在文本元素上使用的自定義字體,你需要使用 DirectWrite 獲取未安裝在用戶系統(tǒng)上的新字體。在示例中,可在 FontFileStreamFontLoader 類中找到加載和提供這些新字體的代碼。

FontFileStream 類是 IDWriteFontFileStream 接口的實(shí)現(xiàn),它接受實(shí)際字體文件并將其加載到應(yīng)用可以編入摘要的表單中。這涉及到讀取文件片段、釋放文件片段、獲取文件大小及獲取***編輯時間的處理方法。

下面是用于讀取和釋放字體文件片段的代碼。

  1. HRESULT STDMETHODCALLTYPE FontFileStream::ReadFileFragment( 
  2.     _Outptr_result_bytebuffer_(fragmentSize) void const** fragmentStart, 
  3.     UINT64 fileOffset, 
  4.     UINT64 fragmentSize, 
  5.     _Out_ void** fragmentContext 
  6.     ) 
  7.     // The loader is responsible for doing a bounds check. 
  8.     if (    fileOffset <= m_data->Length 
  9.         &&  fragmentSize + fileOffset <= m_data->Length 
  10.         ) 
  11.     { 
  12.         *fragmentStart = m_data->Data + static_cast<ULONG>(fileOffset); 
  13.         *fragmentContext = nullptr; 
  14.         return S_OK; 
  15.     } 
  16.     else 
  17.     { 
  18.         *fragmentStart = nullptr; 
  19.         *fragmentContext = nullptr; 
  20.         return E_FAIL; 
  21.     } 
  22.  
  23. void STDMETHODCALLTYPE FontFileStream::ReleaseFileFragment( 
  24.     _In_ void* fragmentContext 
  25.     ) 

#p#

下面是用于檢索文件大小和***編輯時間的代碼。

  1. HRESULT STDMETHODCALLTYPE FontFileStream::GetFileSize( 
  2.     _Out_ UINT64* fileSize 
  3.     ) 
  4.     *fileSize = m_data->Length; 
  5.     return S_OK; 
  6.  
  7. HRESULT STDMETHODCALLTYPE FontFileStream::GetLastWriteTime( 
  8.     _Out_ UINT64* lastWriteTime 
  9.     ) 
  10.     // The concept of last write time does not apply to this loader. 
  11.     *lastWriteTime = 0; 
  12.     return E_NOTIMPL; 

在所有片段均已到位并且你可以訪問字體文件中的信息后,你必須編寫允許你從文件流中構(gòu)造自定義字體集合和字體對象的代碼。可以在 FontLoader.cpp 文件中找到此代碼。

首先,你需要一個函數(shù)用于加載和枚舉你要使用的字體。以下代碼用于 LoadAsync 函數(shù),該函數(shù)查找雜志示例中的字體目錄,并枚舉該目錄中的 .ttf 字體文件列表。

  1. task<void> FontLoader::LoadAsync() 
  2.     // Locate the "fonts" subfolder within the document folder 
  3.     return task<void>([this]() 
  4.     { 
  5.         task<StorageFolder^>(m_location->GetFolderAsync("fonts")).then([=](StorageFolder^ folder) 
  6.         { 
  7.             // Enumerate a list of .TTF files in the storage location 
  8.             auto filters = ref new Platform::Collections::Vector<Platform::String^>(); 
  9.             filters->Append(".ttf"); 
  10.  
  11.             auto queryOptions = ref new QueryOptions(CommonFileQuery::DefaultQuery, filters); 
  12.             auto queryResult = folder->CreateFileQueryWithOptions(queryOptions); 
  13.  
  14.             return queryResult->GetFilesAsync(); 
  15.  
  16.         }).then([=](IVectorView<StorageFile^>^ files) 
  17.         { 
  18.             m_fontFileCount = files->Size; 
  19.  
  20.             std::vector<task<IBuffer^>> tasks; 
  21.  
  22.             for (uint32 i = 0; i < m_fontFileCount; ++i) 
  23.             { 
  24.                 auto file = dynamic_cast<StorageFile^>(files->GetAt(i)); 
  25.  
  26.                 tasks.push_back(task<IBuffer^>(FileIO::ReadBufferAsync(file))); 
  27.             } 
  28.  
  29.             return when_all(tasks.begin(), tasks.end()); 
  30.  
  31.         }).then([=](std::vector<IBuffer^> buffers) 
  32.         { 
  33.             for each (IBuffer^ buffer in buffers) 
  34.             { 
  35.                 auto fileData = ref new Platform::Array<byte>(buffer->Length); 
  36.                 DataReader::FromBuffer(buffer)->ReadBytes(fileData); 
  37.  
  38.                 ComPtr<FontFileStream> fontFileStream(new FontFileStream(fileData)); 
  39.                 m_fontFileStreams.push_back(fontFileStream); 
  40.             } 
  41.  
  42.         }).wait(); 
  43.     }); 

現(xiàn)在,編寫另一個方法,它采用在 DirectWrite 創(chuàng)建自定義字體集合時傳入的字體集合項。此方法將采用此值并返回字體文件枚舉器。

  1. HRESULT STDMETHODCALLTYPE FontLoader::CreateEnumeratorFromKey( 
  2.     _In_ IDWriteFactory* factory, 
  3.     _In_reads_bytes_(fontCollectionKeySize) void const* fontCollectionKey, 
  4.     uint32 fontCollectionKeySize, 
  5.     _Outptr_ IDWriteFontFileEnumerator** fontFileEnumerator 
  6.     ) 
  7.     *fontFileEnumerator = ComPtr<IDWriteFontFileEnumerator>(this).Detach(); 
  8.     return S_OK; 

此方法接受相同的集合項并返回字體文件流。

  1. HRESULT STDMETHODCALLTYPE FontLoader::CreateStreamFromKey( 
  2.     _In_reads_bytes_(fontFileReferenceKeySize) void const* fontFileReferenceKey, 
  3.     uint32 fontFileReferenceKeySize, 
  4.     _Outptr_ IDWriteFontFileStream** fontFileStream 
  5.     ) 
  6.     if (fontFileReferenceKeySize != sizeof(size_t)) 
  7.     { 
  8.         return E_INVALIDARG; 
  9.     } 
  10.  
  11.     size_t fontFileStreamIndex = *(static_cast<size_t const*>(fontFileReferenceKey)); 
  12.  
  13.     *fontFileStream = ComPtr<IDWriteFontFileStream>(m_fontFileStreams.at(fontFileStreamIndex).Get()).Detach(); 
  14.  
  15.     return S_OK; 

接下來的 2 個方法是幫助程序方法。 ***個函數(shù)移到文件流中的下一個字體文件,另一個函數(shù)用作當(dāng)前字體文件的簡單 getter。下面是這 2 種方法的代碼。

  1. HRESULT STDMETHODCALLTYPE FontLoader::MoveNext(OUT BOOL* hasCurrentFile) 
  2.     *hasCurrentFile = FALSE; 
  3.  
  4.     if (m_fontFileStreamIndex < m_fontFileCount) 
  5.     { 
  6.         DX::ThrowIfFailed( 
  7.             m_dwriteFactory->CreateCustomFontFileReference( 
  8.                 &m_fontFileStreamIndex, 
  9.                 sizeof(size_t), 
  10.                 this
  11.                 &m_currentFontFile 
  12.                 ) 
  13.             ); 
  14.  
  15.         *hasCurrentFile = TRUE; 
  16.         ++m_fontFileStreamIndex; 
  17.     } 
  18.  
  19.     return S_OK; 
  20.  
  21. HRESULT STDMETHODCALLTYPE FontLoader::GetCurrentFontFile(OUT IDWriteFontFile** currentFontFile) 
  22.     *currentFontFile = ComPtr<IDWriteFontFile>(m_currentFontFile.Get()).Detach(); 
  23.     return S_OK; 

我們的代碼完成后,你現(xiàn)在已擁有一個異步處理應(yīng)用的正常字體文件加載程序。這 2 個類一起用于枚舉系統(tǒng)上的文件,將它們加載到字體文件流中,并使用你可以使用的這些字體創(chuàng)建一個自定義字體集合。

使用 VSIS 的***實(shí)踐

當(dāng)你希望執(zhí)行 DirectX 和 XAML 互操作時,Windows 8 支持Surface Image SourceVirtual Surface Image Source,但是具體使用哪一個取決于你希望執(zhí)行什么操作。

有 3 個主要方案,每一個都有一個 XAML 互操作選項。

  • 繪制元素(如紋理)作為應(yīng)用中的位圖。
  • 繪制大于屏幕的位圖,因此需要進(jìn)行平移。
  • 改進(jìn)觸摸操作的性能。

如果你需要管理靜態(tài)圖像或偶然更新 SIS 的內(nèi)容,則Surface Image Source是一個好的選擇。當(dāng) SIS 有用時的一個良好示例是,如果你希望將位圖繪制為 XAML UI 元素。此元素可能需要進(jìn)行更新以顯示不同的信息,但是大部分是靜態(tài)的。SIS 能很好地發(fā)揮作用,因?yàn)槟愕膽?yīng)用對 SIS 所做的更新與 XAML UI 線程同步,因此在它需要像應(yīng)用中的 UI 一樣高性能的方案中運(yùn)行得***。

但是如果你需要一個需要直接操作(滾動或平移)的較大位圖或 DirectX 內(nèi)容區(qū)域,則使用 VSIS。如果你要顯示的信息不能容納到屏幕或元素上,則 VSIS 會很有用。一個使用 VSIS 的良好示例是具有滾動文本的閱讀應(yīng)用,或者需要平移和縮放以探索地圖的地圖應(yīng)用。

如果這些方案中沒有一個匹配你的應(yīng)用使用情況,則 VSISSIS 可能不適合你的應(yīng)用。尤其,如果性能對你的應(yīng)用來說很重要,則 XAML 中的 SwapChainBackgroundPanel 元素可能***。有關(guān)詳細(xì)信息,請參閱 Windows.UI::Xaml::Controls::SwapChainBackgroundPanel。

原文鏈接:http://msdn.microsoft.com/zh-cn/library/windows/apps/jj552955.aspx

責(zé)任編輯:陳四芳 來源: microsoft.com
相關(guān)推薦

2013-09-02 16:59:34

JavaScriptHTML

2013-09-03 10:40:45

JavaScriptWindows

2013-09-02 16:52:31

Windows 8.1

2011-09-15 18:43:00

UbuntuchmPDF

2014-12-03 10:46:15

iReader

2017-04-11 13:31:40

閱讀器開源RSS

2009-05-05 09:00:48

RSS瀏覽器

2024-05-16 13:44:18

2011-09-09 10:19:13

2020-03-13 19:26:38

Linux電子書閱讀器桌面應(yīng)用

2014-12-17 15:23:03

Android網(wǎng)絡(luò)閱讀器源碼

2023-09-29 11:47:23

2015-12-03 10:04:36

Ncurses工具LNAV

2022-06-02 14:01:54

屏幕閱讀器NVDAWindows

2023-03-23 13:47:00

LinuxEPUB閱讀器

2009-08-27 09:19:51

RSS閱讀器Web 1.0

2016-12-20 09:29:11

AlduinLinuxRSS

2009-08-25 16:12:46

Visual C#制作

2021-07-29 15:57:11

任意代碼漏洞攻擊

2009-07-29 09:35:07

谷歌離職
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號