<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [**Windows下從源碼編譯Skia**](http://blog.csdn.net/foruok/article/details/50524726)一文介紹了Skia的編譯,現在我們可以嘗試在PPAPI插件中來使用Skia了。 > foruok原創,如需轉載請關注foruok的微信訂閱號“程序視界”聯系foruok。 # Skia的關鍵類庫 官網[https://skia.org/](https://skia.org/)上有文檔,可以看。然后下載的源碼,可以使用SourceInsight之類的工具來查看。具體不再細說,我這里只提用到的三個關鍵類: - [SkPaint](https://skia.org/user/api/skpaint) - [SkCanvas](https://skia.org/user/api/skcanvas) - SkBitmap SkCanvas是畫布,你可以在它上面畫任意的圖元,比如矩形、圓型、文字、弧…… SkPaint則是工具箱,聚合了畫筆、顏色等各種繪畫時要用的配置選項。 SkBitmap代表了一塊圖像數據。 你調用SkCanvas的方法繪制圖元,這些圖元對應的數據一定要有個地方保存或顯示,用于保存或顯示圖像數據的那個角色,被稱為backends。SkCanvas的backends,有好幾種,我們這個簡單的示例ppapi_skia只用到了SkBitmap這種后端。 2D繪圖類庫的基本設計都差不多,我的《[**Qt on Android核心編程**](http://item.jd.com/11571639.html)》一書里對Qt繪圖有介紹,兩廂比對,就會發現設計得差不多。不過有一點不同,QPainter會保存你設置的繪圖選項(顏色、畫筆等),而SkCanvas則不會,需要自己設計數據結構和邏輯來保存。 # ppapi_skia項目 ppapi_skia項目基于ppapi_simple而來,請先參考[**PPAPI插件的繪圖與輸入事件處理**](http://blog.csdn.net/foruok/article/details/50499813)這篇文章。 不過為了方便調用Skia(C++類庫),我這次用了cpp源文件,ppapi_skia.cpp。(吐槽下,VS2013對于C文件的即時提示太弱……) 我還改了ppapi_simple,使用了FlushCompletionCallback來優化繪圖流程。 Skia默認編譯出來的是靜態庫,對于一個簡單的PPAPI+Skia插件,我不知道需要鏈接哪些lib,寫好了代碼,編譯,根據undefined reference錯誤一通狂找,發現要鏈接下列lib: ~~~ skia_core.lib skia_ports.lib skia_utils.lib skia_effects.lib skia_skgpu.lib skia_opts.lib skia_opts_ssse3.lib skia_opts_sse41.lib skia_opts_avx.lib skia_images.lib skia_sfnt.lib libetc1.lib libSkKTX.lib opengl32.lib ~~~ [**Windows下從源碼編譯Skia**](http://blog.csdn.net/foruok/article/details/50524726)一文提到編譯后的lib文件路徑是:E:\sources\skia\out\Release。設置到項目的附加庫目錄列表中。skia還依賴其他一些庫文件,在E:\sources\skia\out\Release\obj\gyp目錄下,把這個目錄添加到附加庫目錄列表里。 Skia需要OpenGL,我們得鏈接Opengl32.lib,Windows SDK里有。 skia編譯時加了/MD參數,CEF編譯時用的MT,如果你用PPAPI的C++接口,就會沖突了。要么改skia,要么改CEF。skia庫小,改它吧。我還沒找到怎么在生成構建文件時設置,最簡單直接的,就是到E:\sources\skia\out\Release\obj\gyp這里,把*.ninja文件里的/MD都修改為/MT。然后重新編譯。 如過用C接口,沒關系,把PPAPI的代碼生成選項里的運行庫修改為MD即可。我偷懶,就用C接口,把ppapi_skia項目的運行庫選項設置為了MD。 好,關于工程基本就這樣了。 # 源碼 分C++源碼和HTML源碼。 ### C++代碼 So,源碼來了,基于C代碼改過來,有點亂,不過可以說明用法。 ~~~ /* * Copyright (c) 2016 foruok@程序視界. All rights reserved. * 2016-1-16, edited by foruok. * 如需轉載,請關注微信訂閱號“程序視界”,回復foruok獲取其聯系方式 */ #include <stdint.h> #include <stdlib.h> #include <string.h> #include <Windows.h> #include <tchar.h> #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_var.h" #include "ppapi/c/ppb.h" #include "ppapi/c/ppb_core.h" #include "ppapi/c/ppb_graphics_2d.h" #include "ppapi/c/ppb_image_data.h" #include "ppapi/c/ppb_instance.h" #include "ppapi/c/ppb_view.h" #include "ppapi/c/ppp.h" #include "ppapi/c/ppp_instance.h" #include "ppapi/c/ppb_input_event.h" #include "ppapi/c/ppp_input_event.h" #include "SkPaint.h" #include "SkBitmap.h" #include "SkCanvas.h" PPB_GetInterface g_get_browser_interface = NULL; const PPB_Core* g_core_interface; const PPB_Graphics2D* g_graphics_2d_interface; const PPB_ImageData* g_image_data_interface; const PPB_Instance* g_instance_interface; const PPB_View* g_view_interface; const PPB_InputEvent *g_input_interface; const PPB_MouseInputEvent *g_mouse_interface; /* PPP_Instance implementation -----------------------------------------------*/ struct InstanceInfo { PP_Instance pp_instance; struct PP_Size last_size; PP_Resource graphics; PP_Resource image; SkBitmap *bitmap; SkCanvas *canvas; int inFlush; int requestPaint; unsigned int colorIndex; struct InstanceInfo* next; }; /** Linked list of all live instances. */ struct InstanceInfo* all_instances = NULL; /** Returns a refed resource corresponding to the created graphics 2d. */ PP_Resource MakeAndBindGraphics2D(PP_Instance instance, const struct PP_Size* size) { PP_Resource graphics; graphics = g_graphics_2d_interface->Create(instance, size, PP_FALSE); if (!graphics) return 0; if (!g_instance_interface->BindGraphics(instance, graphics)) { g_core_interface->ReleaseResource(graphics); return 0; } return graphics; } unsigned int g_colors[4] = { 0xFF0000FF, 0xFFFF00FF, 0xFF00FFFF, 0xFFEA00FF }; void DoPaint(struct InstanceInfo * instance); void FlushCompletionCallback(void* user_data, int32_t result) { struct InstanceInfo *inst = (struct InstanceInfo*)user_data; inst->inFlush = 0; if (inst->requestPaint) { inst->requestPaint = 0; DoPaint(inst); } } const char szHelloSkia[] = "Hello Skia in PPAPI"; void DoPaint(struct InstanceInfo * instance) { instance->inFlush = 1; instance->colorIndex++; if (instance->colorIndex >= sizeof(g_colors) / sizeof(g_colors[0])) instance->colorIndex = 0; /* [2] Skia Paint * foruok */ instance->canvas->drawColor(g_colors[instance->colorIndex]); SkPaint paint; paint.setColor(SK_ColorWHITE); paint.setAntiAlias(true); paint.setLCDRenderText(true); paint.setStrokeWidth(4); instance->canvas->drawText(szHelloSkia, ARRAYSIZE(szHelloSkia) - 1, 20.0f, 20.0f, paint); paint.setColor(0x80CCCCCC); instance->canvas->drawCircle(150, 130, 100, paint); /* Paint image to graphics 2d. */ g_graphics_2d_interface->ReplaceContents(instance->graphics, instance->image); g_graphics_2d_interface->Flush(instance->graphics, PP_MakeCompletionCallback(&FlushCompletionCallback, instance)); } void Repaint(struct InstanceInfo* instance, const struct PP_Size* size) { /* Ensure the graphics 2d is ready. */ if (!instance->graphics) { instance->graphics = MakeAndBindGraphics2D(instance->pp_instance, size); if (!instance->graphics) return; } /* Create image data to paint into. */ if (!instance->image) { instance->image = g_image_data_interface->Create( instance->pp_instance, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, PP_TRUE); if (!instance->image) return; } /* [1] setup SkCanvas's backends * foruok */ if (!instance->bitmap) { /* foruok * get image data from PPB interfaces */ struct PP_ImageDataDesc image_desc; uint32_t* image_data; g_image_data_interface->Describe(instance->image, &image_desc); image_data = (uint32_t*)g_image_data_interface->Map(instance->image); if (!image_data) { g_core_interface->ReleaseResource(instance->image); return; } /* foruok * bind PPAPI image data to SkBitmap */ SkImageInfo ii = SkImageInfo::Make(size->width, size->height, kBGRA_8888_SkColorType, kPremul_SkAlphaType, kLinear_SkColorProfileType); instance->bitmap = new SkBitmap(); instance->bitmap->installPixels(ii, image_data, image_desc.stride); if (!instance->canvas) { /* foruok * construct SkCanvas with SkBitmap backend */ instance->canvas = new SkCanvas(*instance->bitmap); } } if (!instance->inFlush) { DoPaint(instance); } else { instance->requestPaint = 1; } } /** Returns the info for the given instance, or NULL if it's not found. */ struct InstanceInfo* FindInstance(PP_Instance instance) { struct InstanceInfo* cur = all_instances; while (cur) { if (cur->pp_instance == instance) return cur; cur = cur->next; } return NULL; } PP_Bool Instance_DidCreate(PP_Instance instance, uint32_t argc, const char* argn[], const char* argv[]) { struct InstanceInfo* info = (struct InstanceInfo*)calloc(1, sizeof(struct InstanceInfo)); info->pp_instance = instance; /* Insert into linked list of live instances. */ info->next = all_instances; all_instances = info; g_input_interface->RequestInputEvents(instance, PP_INPUTEVENT_CLASS_MOUSE); g_input_interface->RequestFilteringInputEvents(instance, PP_INPUTEVENT_CLASS_MOUSE); OutputDebugString(_T("Instance_DidCreate\r\n")); return PP_TRUE; } void Instance_DidDestroy(PP_Instance instance) { /* Find the matching item in the linked list, delete it, and patch the * links. */ struct InstanceInfo** prev_ptr = &all_instances; struct InstanceInfo* cur = all_instances; while (cur) { if (instance == cur->pp_instance) { *prev_ptr = cur->next; g_core_interface->ReleaseResource(cur->graphics); free(cur); return; } prev_ptr = &cur->next; cur = cur->next; } } void Instance_DidChangeView(PP_Instance pp_instance, PP_Resource view) { struct PP_Rect position; struct InstanceInfo* info = FindInstance(pp_instance); if (!info) return; if (g_view_interface->GetRect(view, &position) == PP_FALSE) return; if (info->last_size.width != position.size.width || info->last_size.height != position.size.height) { /* Got a resize, repaint the plugin. */ Repaint(info, &position.size); info->last_size.width = position.size.width; info->last_size.height = position.size.height; } OutputDebugString(_T("Instance_DidChangeView\r\n")); } void Instance_DidChangeFocus(PP_Instance pp_instance, PP_Bool has_focus) { } PP_Bool Instance_HandleDocumentLoad(PP_Instance pp_instance, PP_Resource pp_url_loader) { return PP_FALSE; } static PPP_Instance instance_interface = { &Instance_DidCreate, &Instance_DidDestroy, &Instance_DidChangeView, &Instance_DidChangeFocus, &Instance_HandleDocumentLoad }; PP_Bool InputEvent_HandleInputEvent(PP_Instance instance, PP_Resource input_event) { struct PP_Point pt; TCHAR szLog[512] = { 0 }; switch (g_input_interface->GetType(input_event)) { case PP_INPUTEVENT_TYPE_MOUSEDOWN: pt = g_mouse_interface->GetPosition(input_event); _stprintf_s(szLog, 512, _T("InputEvent_HandleInputEvent, mouse down at [%d, %d]\r\n"), pt.x, pt.y); OutputDebugString(szLog); break; /* case PP_INPUTEVENT_TYPE_MOUSEUP: OutputDebugString(_T("InputEvent_HandleInputEvent, mouse up\r\n")); break; case PP_INPUTEVENT_TYPE_MOUSEMOVE: OutputDebugString(_T("InputEvent_HandleInputEvent, mouse move\r\n")); break; case PP_INPUTEVENT_TYPE_MOUSEENTER: OutputDebugString(_T("InputEvent_HandleInputEvent, mouse enter\r\n")); break; case PP_INPUTEVENT_TYPE_MOUSELEAVE: OutputDebugString(_T("InputEvent_HandleInputEvent, mouse leave\r\n")); break; */ default: return PP_FALSE; } struct InstanceInfo* info = FindInstance(instance); if (info && info->last_size.width > 0) { Repaint(info, &info->last_size); } return PP_TRUE; } static PPP_InputEvent input_interface = { &InputEvent_HandleInputEvent }; /* Global entrypoints --------------------------------------------------------*/ PP_EXPORT int32_t PPP_InitializeModule(PP_Module module, PPB_GetInterface get_browser_interface) { g_get_browser_interface = get_browser_interface; g_core_interface = (const PPB_Core*) get_browser_interface(PPB_CORE_INTERFACE); g_instance_interface = (const PPB_Instance*) get_browser_interface(PPB_INSTANCE_INTERFACE); g_image_data_interface = (const PPB_ImageData*) get_browser_interface(PPB_IMAGEDATA_INTERFACE); g_graphics_2d_interface = (const PPB_Graphics2D*) get_browser_interface(PPB_GRAPHICS_2D_INTERFACE); g_view_interface = (const PPB_View*) get_browser_interface(PPB_VIEW_INTERFACE); g_input_interface = (const PPB_InputEvent*)get_browser_interface(PPB_INPUT_EVENT_INTERFACE); g_mouse_interface = (const PPB_MouseInputEvent*)get_browser_interface(PPB_MOUSE_INPUT_EVENT_INTERFACE); if (!g_core_interface || !g_instance_interface || !g_image_data_interface || !g_graphics_2d_interface || !g_view_interface || !g_input_interface || !g_mouse_interface) return -1; OutputDebugString(_T("PPP_InitializeModule\r\n")); return PP_OK; } PP_EXPORT void PPP_ShutdownModule() { } PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { OutputDebugString(_T("PPP_GetInterface, instance_interface\r\n")); return &instance_interface; } else if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0) { OutputDebugString(_T("PPP_GetInterface, input_interface\r\n")); return &input_interface; } return NULL; } ~~~ 上面代碼里我標注了兩處與Skia有關的改動,[1]和[2],也加了注釋。另外就是使用FlushCompletionCallback來處理繪圖和刷新,把ppapi_simple中的一些全局變量修改為與插件實例對象綁定的變量,這樣可以支持一個網頁里嵌入多個plugin了。 ### HTML代碼 ppapi_skia.html代碼如下: ~~~ <!DOCTYPE html> <html> <!-- Copyright (c) 2016 foruok. All rights reserved. 如需轉載,請關注微信訂閱號“程序視界”,回復foruok獲取其聯系方式 --> <head> <title>PPAPI-SKIA</title> </head> <body> <embed id="plugin" type="application/x-ppapi-skia" width="400px" height="300px"> </body> </html> ~~~ ### 運行效果 使用下面命令來運行: ~~~ cefsimple.exe --ppapi-out-of-process --register-pepper-plugins="E:\sources\CEF\2526\chromium\src\cef\binary_distrib\cef_binary_3.2526.1364.gf6bf57b_windows32\Release\ppapi_skia.dll;application/x-ppapi-skia" --url=file:///E:/sources/CEF/2526/chromium/src/cef/binary_distrib/cef_binary_3.2526.1364.gf6bf57b_windows32/Release/ppapi_skia.html ~~~ 效果如下: ![PPAPI-Skia](https://box.kancloud.cn/2016-02-22_56caac346903b.jpg "") Ok,這個示例就這么著了。有時間我會用Skia+PPAPI的方式制作一個簡單的涂鴉板插件。 其他參考文章: - [**CEF Windows開發環境搭建**](http://blog.csdn.net/foruok/article/details/50468642) - [**CEF加載PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485448) - [**VS2013編譯最簡單的PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485461) - [**理解PPAPI的設計**](http://blog.csdn.net/foruok/article/details/50486788) - [**PPAPI插件與瀏覽器的交互過程**](http://blog.csdn.net/foruok/article/details/50494061) - [**Windows下從源碼編譯CEF**](http://blog.csdn.net/foruok/article/details/50498740) - [**編譯PPAPI的media_stream_video示例**](http://blog.csdn.net/foruok/article/details/50498873) - [**PPAPI插件的繪圖與輸入事件處理**](http://blog.csdn.net/foruok/article/details/50499813) - [**在PPAPI插件中創建本地窗口**](http://blog.csdn.net/foruok/article/details/50513228) - [**PPAPI插件與瀏覽器的通信**](http://blog.csdn.net/foruok/article/details/50513315) - [**Windows下從源碼編譯Skia**](http://blog.csdn.net/foruok/article/details/50524726)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看