精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

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

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

隨著平板電腦變得越來越普及,融合了閱讀體驗的應(yīng)用很快就會變得流行起來。 下面我們介紹如何使用 DirectX、C++ 和 XAML 創(chuàng)建豐富的文檔閱讀器應(yīng)用。我們涵蓋了此類型應(yīng)用的結(jié)構(gòu)、技術(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 和圖像源之間的交互操作這一事實。

當(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)信息。接下來,你必須實現(xiàn)當(dāng)你需要更新內(nèi)容時 VSIS 調(diào)用的回調(diào)方法。

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

下面的代碼向你顯示了如何實現(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#

實現(xiàn)回調(diào)后,你的應(yīng)用現(xiàn)在將從 VSIS 接收有關(guān)你需要繪制的區(qū)域的信息。你的 draw 函數(shù)只需要獲取此矩形,并繪制到 VSIS 的右側(cè)區(qū)域中。通過實現(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 中。

因為 .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)建 FlipViewDataTemplateScrollViewer 類的實例。然后,將該信息綁定到那些 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ù)綁定。現(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 中實現(xiàn)異步字體加載程序和集合。在 DirectX 應(yīng)用中,如果你希望提供一個要在文本元素上使用的自定義字體,你需要使用 DirectWrite 獲取未安裝在用戶系統(tǒng)上的新字體。在示例中,可在 FontFileStreamFontLoader 類中找到加載和提供這些新字體的代碼。

FontFileStream 類是 IDWriteFontFileStream 接口的實現(xiàn),它接受實際字體文件并將其加載到應(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 的***實踐

當(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īng)用對 SIS 所做的更新與 XAML UI 線程同步,因此在它需要像應(yīng)用中的 UI 一樣高性能的方案中運行得***。

但是如果你需要一個需要直接操作(滾動或平移)的較大位圖或 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ò)閱讀器源碼

2015-12-03 10:04:36

Ncurses工具LNAV

2023-09-29 11:47:23

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

2021-05-21 05:26:02

谷歌Chrome 瀏覽器

2009-07-29 09:35:07

谷歌離職

2021-07-29 15:57:11

任意代碼漏洞攻擊
點贊
收藏

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

日韩专区一区二区| 国产无遮挡aaa片爽爽| 成人一区视频| 亚洲欧美色综合| 久久久精品有限公司| 青青国产在线视频| 欧美~级网站不卡| 亚洲欧美精品中文字幕在线| 国产免费中文字幕| 美女高潮在线观看| 中文字幕永久在线不卡| 精品视频免费观看| 在线观看日批视频| 一区二区三区成人精品| 久久国产精品久久久久久电车| 国产精品久久99| 精品视频导航| 国产熟女精品视频| 快she精品国产999| 欧美激情一级精品国产| 纪美影视在线观看电视版使用方法| 一区二区三区欧洲区| 欧美视频一区二区三区四区| 国产无限制自拍| 黄色网址视频在线观看| 久久综合色之久久综合| 国产99在线播放| 99热这里只有精品在线| 奇米色一区二区三区四区| 69av视频在线播放| 欧美激情国产精品免费| 国产精品国产一区| 在线视频日本亚洲性| 一本色道综合久久欧美日韩精品 | 中文字幕乱视频| 国产精品一区二区三区av| 91福利在线观看| 凹凸国产熟女精品视频| av丝袜在线| 亚洲一区二区av在线| 日日噜噜夜夜狠狠久久丁香五月 | www.成人.com| 久久久综合视频| 精品卡一卡二| 性感美女福利视频| jizz一区二区| 国产精品免费一区二区三区四区| 国产免费黄色录像| 精品一区二区三区不卡 | 国产成人久久精品一区二区三区| 欧美日韩一二三| 九九视频精品在线观看| 性欧美超级视频| 色网综合在线观看| 成年人网站大全| 午夜av成人| 在线观看免费一区| 日韩在线免费观看视频| 国产又黄又猛的视频| 国产欧美在线观看免费| 欧美三级蜜桃2在线观看| 亚洲 欧美 另类人妖| 日本国产欧美| 欧美精品一二三四| 亚洲成人激情小说| julia中文字幕一区二区99在线| 日韩欧美激情在线| 精品人妻在线视频| 狼人精品一区二区三区在线| 亚洲激情久久久| 国产精品亚洲无码| 欧美熟乱15p| 久久久精品久久久| 国产一级视频在线| 香蕉国产精品偷在线观看不卡| 青青在线视频一区二区三区| 欧美brazzers| 韩国女主播成人在线观看| 亚洲自拍偷拍色片视频| 国模无码一区二区三区| 2023国产精品视频| 亚洲午夜精品福利| 中文字幕中文字幕在线中高清免费版 | 欧美日韩精品二区| 永久免费的av网站| 亚洲性视频在线| 亚洲剧情一区二区| 国产中文字幕久久| 黄色日韩在线| 国产精品久久999| 国产suv一区二区| 99国产一区二区三精品乱码| 午夜免费电影一区在线观看| 2024最新电影免费在线观看| 欧美日韩色婷婷| caoporm在线视频| 青青草久久爱| 久久夜色精品国产亚洲aⅴ| 日本天堂在线视频| 国产又大又黄的视频| 日韩在线a电影| 91久久久一线二线三线品牌| 毛片在线免费| 亚洲午夜免费电影| 亚洲欧美自偷自拍另类| 国产精品网址| 久久久91精品国产| 免费av网站在线| 成人亚洲一区二区一| 亚洲国产精品久久久久婷婷老年| sis001亚洲原创区| 欧美日韩国产高清一区二区| 国产精品1000部啪视频| 午夜精品999| 国产精品视频yy9099| 欧洲成人一区二区三区| 亚洲日本成人在线观看| 欧美三级理论片| 亚州综合一区| 色综合91久久精品中文字幕| 亚洲视频在线观看一区二区| 99精品欧美一区二区蜜桃免费 | 久久久久国产精品无码免费看| 国产精品7m凸凹视频分类| 日本亚洲欧洲色| 国精产品乱码一区一区三区四区| 国产精品成人一区二区艾草| 五月婷婷深爱五月| 精品中文一区| 97香蕉久久夜色精品国产| 精品毛片一区二区三区| 国产精品久久久久9999吃药| 黄色一级二级三级| 久久综合欧美| 日本精品va在线观看| 黄色小视频免费在线观看| 亚洲精品日产精品乱码不卡| 自拍偷拍21p| 大色综合视频网站在线播放| 国产91露脸中文字幕在线| 亚洲av成人无码久久精品老人| 亚洲亚洲精品在线观看| 99999精品| 亚洲九九在线| 91老司机精品视频| 国产午夜精品久久久久免费视| 国语自产精品视频在线看8查询8| 久久久亚洲天堂| 午夜精品在线播放| 亚洲一区二区三区自拍| 人妻 丝袜美腿 中文字幕| 欧美韩国一区| 国产精品9999久久久久仙踪林| 色呦呦在线观看视频| 欧美videos大乳护士334| 久久久久久久九九九九| 懂色av一区二区三区免费观看| 成人毛片100部免费看| 一区二区三区国产好| 久久久噜噜噜久噜久久| 无码精品人妻一区二区三区影院| 日韩欧美极品在线观看| 91成年人网站| 蜜臀久久99精品久久久久久9 | 午夜精品国产| 国产精品国产三级国产专区53 | 四虎国产精品成人免费入口| 久久婷婷一区| 一区二区三区四区视频在线| 亚洲精品成人一区| 色综合久久88| 欧美日韩在线中文字幕| 欧洲激情一区二区| 欧美激情图片小说| 成人sese在线| 国产亚洲天堂网| 日韩在线理论| 超碰97在线播放| 综合毛片免费视频| 中文字幕亚洲一区| 性欧美一区二区三区| 五月天激情小说综合| 性の欲びの女javhd| 国产一区二区三区免费看| 日本欧美视频在线观看| 激情综合网站| 99re6在线| 日韩成人影音| 欧美大片免费看| 欧美日本韩国一区二区| 欧美精品视频www在线观看| 久草免费在线观看视频| 国产偷v国产偷v亚洲高清| 久久色精品视频| 黄色网址中文字幕| 日韩美女啊v在线免费观看| 亚洲av成人精品一区二区三区 | 青青青国产精品一区二区| 老司机av在线免费看| 亚洲黄色片网站| 国产女人爽到高潮a毛片| 精品动漫一区二区| 久久久久久久久久97| 91亚洲国产成人精品一区二区三| 亚洲天堂国产视频| 国产亚洲一区在线| 国产人妻互换一区二区| 三级小说欧洲区亚洲区| 91亚洲精品一区| 嫩草伊人久久精品少妇av杨幂| 色综合久综合久久综合久鬼88 | 26uuu日韩精品一区二区| 欧美成人xxx| 亚洲视频专区在线| 亚洲成a人片77777精品| 欧美日韩高清在线| 在线观看日本网站| 欧美日韩国产精品一区| 极品盗摄国产盗摄合集| 国产精品国产三级国产| 精品少妇人妻一区二区黑料社区 | 9色精品在线| 777久久精品一区二区三区无码 | www欧美日韩| 久青青在线观看视频国产| 精品久久久网站| 国产免费黄色录像| 欧美巨大另类极品videosbest| 丰满少妇xoxoxo视频| 午夜激情综合网| 久久国产免费观看| 亚洲一区二区三区四区不卡| 黄色一级大片在线免费观看| 国产精品美女久久久久久2018| 深爱五月激情网| 91麻豆精品一区二区三区| 欧美日韩人妻精品一区在线| 国产精品亚洲成人| 手机精品视频在线| 国产一区二区三区四| 国产美女视频免费看| 久久99精品久久久久久| 日韩视频免费观看高清在线视频| 精品一区免费观看| 亚洲午夜视频在线| 久久综合激情网| 亚洲一级片在线观看| 欧美日韩大片在线观看| 一区二区国产视频| 久久亚洲AV无码| 亚洲高清在线精品| 久草视频在线资源| 亚洲国产日韩av| 日韩毛片在线播放| 欧美日韩亚洲激情| 成年人视频免费| 欧美性一区二区| 91国内精品视频| 欧美一级免费大片| 精品人妻久久久久一区二区三区| 日韩免费性生活视频播放| 午夜精品久久久久久久99老熟妇| 亚洲成av人片在线观看香蕉| 日本国产在线观看| 日韩精品中文字| 爱久久·www| 久久夜色精品亚洲噜噜国产mv | 欧美日韩中字| 在线观看亚洲视频啊啊啊啊| 亚洲网色网站| 福利视频一二区| 噜噜噜躁狠狠躁狠狠精品视频| 天天干在线影院| 美国一区二区三区在线播放| 人妻换人妻仑乱| 99久久久国产精品| 欧美成人另类视频| 依依成人精品视频| 在线观看 中文字幕| 欧美性欧美巨大黑白大战| 国产一区二区在线视频聊天| 亚洲国产精品99久久| 美国一级片在线免费观看视频 | 欧美成人福利视频| 日本护士...精品国| 俺去啦;欧美日韩| √8天堂资源地址中文在线| 国产激情久久久久| 久久久久久久久成人| 久中文字幕一区| 99热国内精品永久免费观看| 日日摸日日碰夜夜爽无码| 日产欧产美韩系列久久99| 精人妻一区二区三区| 国产亚洲精品精华液| 久久久国产精品黄毛片| 色国产精品一区在线观看| 精品久久久免费视频| 亚洲人永久免费| 国产一线二线在线观看| 国产精品久久久久影院日本| 久久影院资源站| 只有这里有精品| 日韩 欧美一区二区三区| 中文字幕99页| 波多野结衣在线aⅴ中文字幕不卡 波多野结衣在线一区 | 日韩av在线天堂| 欧美美女黄视频| 成年人二级毛片| 国产大片一区| 91精品一区二区三区四区| 日韩电影在线免费| 日韩av手机在线播放| 亚洲精品国产a久久久久久| 中文字幕av在线免费观看| 亚洲国产精品久久久| 最新黄网在线观看| 国产免费一区二区三区在线观看 | 经典三级一区二区| 国产一区免费| 亚洲国产99| 韩国三级在线播放| 《视频一区视频二区| 综合久久中文字幕| 亚洲欧洲日产国码av系列天堂| 男女视频在线| 91在线观看免费高清| 四虎国产精品免费观看| 蜜臀视频一区二区三区| 91女厕偷拍女厕偷拍高清| 国产精品99re| 精品久久久久久无| 久草在线资源站资源站| 亚洲free性xxxx护士白浆| 99欧美视频| 亚洲女人在线观看| 亚洲天天做日日做天天谢日日欢| 日韩欧美一级大片| 国产亚洲综合久久| 国模视频一区| 亚洲激情图片| 日韩av一二三| 老司机精品免费视频| 欧美色倩网站大全免费| 91电影在线播放| 国产欧美日韩高清| 久久一级电影| 欧美性受xxxx黒人xyx性爽| 国产精品久久久久影院亚瑟 | 麻豆疯狂做受xxxx高潮视频| 欧美一级在线观看| 欧洲黄色一区| 国外成人免费视频| 亚洲欧美日韩国产一区| 污污内射在线观看一区二区少妇| 亚洲高清一区二区三区| 天天色天天操天天射| 欧美怡春院一区二区三区| 国产一区不卡| 亚洲一区日韩精品| 日韩一区中文字幕| 成人黄色免费视频| 国产精品亚洲午夜一区二区三区| 少妇人妻互换不带套| 国产日韩精品一区二区三区 | 日本不卡免费新一二三区| 日本成人中文字幕| 糖心vlog免费在线观看| 日韩一区二区三区四区| free性欧美| 日本一区高清在线视频| 麻豆一区二区三| 欧美成人片在线观看| 精品爽片免费看久久| jizz免费一区二区三区| 少妇高潮大叫好爽喷水| 91婷婷韩国欧美一区二区| 在线观看你懂的网站| 久久伊人免费视频| 福利欧美精品在线| 免费黄色日本网站| 国产精品久久久久久久久搜平片 | 中文字幕日韩免费| www.久久色.com| 激情av综合| 亚洲这里只有精品| 亚洲国产精品久久久久秋霞影院 | 中文字幕一区二区三区色视频| 99在线精品视频免费观看软件 | 无码人妻精品一区二区50| www.xxxx欧美| 牛牛精品成人免费视频| 日本黄大片一区二区三区| 亚洲国产你懂的| √新版天堂资源在线资源| 国产伦精品一区二区三区免| 日本不卡一区二区| 日韩精品成人在线| 久久精品在线视频| 欧美极品中文字幕|