Старожил
Сообщения: 467
Благодарности: 25
|
Профиль
|
Отправить PM
| Цитировать
Вот в Release конфигурации получаю странный Access violation (0xC0000005: Access violation reading location 0x5e33e279). В Debug конфигурации все отлично. Валится после нажатия кнопки "хрестик". И самое главное, валится только из Студии, если просто запустить, выходит нормально, возвращает 0. Валится в __tmainCRTStartup на строчке "while (*lpszCommandLine > SPACECHAR || *lpszCommandLine&&inDoubleQuote)) {" (512 линия crtexe.c). lpszCommandLine на момент Access violation пустая, это может быть причиной? И еще странно, почему __tmainCRTStartup вызывается при закрытии приложения? ![Smile](images/smilies/new/smile.gif) (логика подсказывает, что должно вызываться в начале выполнения)
Если надо, код программы:
код, большой и непонятный
Код: ![Выделить весь код](images/misc/selectcode.png)
// cairo_test.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "cairo_test.h"
#include <cairo.h>
#include <cairo-win32.h>
#include <cairo-ft.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype/ftadvanc.h>
#include <freetype/ftsnames.h>
#include <freetype/tttables.h>
#include <hb.h>
#include <hb-ft.h>
#include <hb-buffer.h>
#include <harfbuzz_unicode_funcs.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void init();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
//UNREFERENCED_PARAMETER(hPrevInstance);
//UNREFERENCED_PARAMETER(lpCmdLine);
init();
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CAIRO_TEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CAIRO_TEST));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//return (int) msg.wParam;
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CAIRO_TEST));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CAIRO_TEST);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
wchar_t *texts[5] = {
L"This is some english text",
L"??? ?? ??? ?????? ??????",
L"??????",
L"Это пример русского текста, с различными символами !%?(*%№ ёЁъЪ",
L"Це приклад українського тексту, з різнимим символами !%?(*%№ ї"
};
const hb_direction_t text_directions[5] = {
HB_DIRECTION_LTR,
HB_DIRECTION_RTL,
HB_DIRECTION_LTR,
HB_DIRECTION_LTR,
HB_DIRECTION_LTR
};
/* XXX: I don't know if these are correct or not, it doesn't seem to break anything
* regardless of their value. */
const char *languages[5] = {
"en",
"ar",
"ch",
"ru",
"ua"
};
const hb_script_t scripts[5] = {
HB_SCRIPT_LATIN,
HB_SCRIPT_ARABIC,
HB_SCRIPT_HAN,
HB_SCRIPT_CYRILLIC,
HB_SCRIPT_CYRILLIC
};
enum {
ENGLISH=0, ARABIC, CHINESE, RUSSIAN, UKRAINE
};
double ptSize = 50.0;
int device_hdpi = 100;
int device_vdpi = 100;
FT_Face ft_face[5];
cairo_font_face_t *cairo_ft_face[5];
hb_font_t *hb_ft_font[5];
hb_face_t *hb_ft_face[5];
void init()
{
/* Init freetype */
int error = 0;
FT_Library ft_library;
error = FT_Init_FreeType(&ft_library);
/* Load our fonts */
error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\DejaVuSerif.ttf", 0, &ft_face[ENGLISH]);
error = FT_Set_Char_Size(ft_face[ENGLISH], 0, ptSize, device_hdpi, device_vdpi );
error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\lateef.ttf", 0, &ft_face[ARABIC]);
error = FT_Set_Char_Size(ft_face[ARABIC], 0, ptSize, device_hdpi, device_vdpi );
error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\fireflysung-1.3.0\\fireflysung.ttf", 0, &ft_face[CHINESE]);
error = FT_Set_Char_Size(ft_face[CHINESE], 0, ptSize, device_hdpi, device_vdpi );
error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\DejaVuSerif.ttf", 0, &ft_face[RUSSIAN]);
error = FT_Set_Char_Size(ft_face[RUSSIAN], 0, ptSize, device_hdpi, device_vdpi );
error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\DejaVuSerif.ttf", 0, &ft_face[UKRAINE]);
error = FT_Set_Char_Size(ft_face[UKRAINE], 0, ptSize, device_hdpi, device_vdpi );
//assert(!FT_Select_Charmap(ft_face[CHINESE],FT_Encoding::FT_ENCODING_MS_SYMBOL));
/* Get our cairo font structs */
cairo_ft_face[ENGLISH] = cairo_ft_font_face_create_for_ft_face(ft_face[ENGLISH], 0);
cairo_ft_face[ARABIC] = cairo_ft_font_face_create_for_ft_face(ft_face[ARABIC], 0);
cairo_ft_face[CHINESE] = cairo_ft_font_face_create_for_ft_face(ft_face[CHINESE], 0);
cairo_ft_face[RUSSIAN] = cairo_ft_font_face_create_for_ft_face(ft_face[RUSSIAN], 0);
cairo_ft_face[UKRAINE] = cairo_ft_font_face_create_for_ft_face(ft_face[UKRAINE], 0);
/* Get our harfbuzz font/face structs */
hb_ft_font[ENGLISH] = hb_ft_font_create(ft_face[ENGLISH], NULL);
hb_ft_face[ENGLISH] = hb_ft_face_create(ft_face[ENGLISH], NULL);
hb_ft_font[ARABIC] = hb_ft_font_create(ft_face[ARABIC] , NULL);
hb_ft_face[ARABIC] = hb_ft_face_create(ft_face[ARABIC] , NULL);
hb_ft_font[CHINESE] = hb_ft_font_create(ft_face[CHINESE], NULL);
hb_ft_face[CHINESE] = hb_ft_face_create(ft_face[CHINESE], NULL);
hb_ft_font[RUSSIAN] = hb_ft_font_create(ft_face[RUSSIAN], NULL);
hb_ft_face[RUSSIAN] = hb_ft_face_create(ft_face[RUSSIAN], NULL);
hb_ft_font[UKRAINE] = hb_ft_font_create(ft_face[UKRAINE], NULL);
hb_ft_face[UKRAINE] = hb_ft_face_create(ft_face[UKRAINE], NULL);
}
void cr_draw(cairo_t *cr)
{
// cairo_set_source_rgba (cr, 0.3, 0.6, 1, 1);
// cairo_paint (cr);
// cairo_set_source_rgba (cr, 0, 0, 0, 1);
int x = 0;
int y = 100;
for (int i=0; i < 5; ++i) {
x = 0;
/* Create a buffer for harfbuzz to use */
hb_buffer_t *buf = hb_buffer_create();
//alternatively you can use hb_buffer_set_unicode_funcs(buf, hb_glib_get_unicode_funcs());
hb_buffer_set_unicode_funcs(buf, hb_moz_get_unicode_funcs());
hb_buffer_set_direction(buf, text_directions[i]); /* or LTR */
hb_buffer_set_script(buf, scripts[i]); /* see hb-unicode.h */
hb_buffer_set_language(buf, hb_language_from_string(languages[i],2));
/* Layout the text */
for(int k = 0; k < wcslen(texts[i]);k++)
{
hb_buffer_add(buf,texts[i][k],0,0);
}
hb_shape(hb_ft_font[i], buf, NULL, 0);
/* Hand the layout to cairo to render */
int glyph_count = hb_buffer_get_length(buf);
unsigned int size = (unsigned int) glyph_count;
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf,&size);
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf,&size);
cairo_glyph_t *cairo_glyphs = (cairo_glyph_t *)malloc(sizeof(cairo_glyph_t) * glyph_count);
for (int i=0; i < glyph_count; ++i) {
cairo_glyphs[i].index = glyph_info[i].codepoint;
//cairo_glyphs[i].index = FT_Get_Char_Index(ft_face[CHINESE],L'Ы');
cairo_glyphs[i].x = x;
cairo_glyphs[i].y = y;
x += glyph_pos[i].x_advance/64;
y += glyph_pos[i].y_advance/64;
}
cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 1.0);
cairo_set_font_face(cr, cairo_ft_face[i]);
cairo_set_font_size(cr, ptSize);
cairo_show_glyphs(cr, cairo_glyphs, glyph_count);
free(cairo_glyphs);
hb_buffer_destroy(buf);
y += 100;
}
}
int nWidth;
int nHeight;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_about:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
cairo_surface_t *surface;
cairo_t *cr;
//surface = cairo_win32_surface_create(hdc);
surface = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
cr = cairo_create (surface);
cr_draw(cr);
HDC src = cairo_win32_surface_get_dc(surface); // <--------
BitBlt(hdc, 0, 0, nWidth, nHeight, src, 0,0, SRCCOPY); // <--------
cairo_destroy(cr);
cairo_surface_destroy(surface);
//cairo_surface_t *surface;
//cairo_t *cr;
//surface = cairo_win32_surface_create(hdc);
//cr = cairo_create(surface);
//cr_draw(cr); // <<<<<<Cairo draw here
//cairo_destroy(cr);
EndPaint(hWnd, &ps);
break;
}
case WM_SIZE:
{
nWidth = LOWORD(lParam);
nHeight = HIWORD(lParam);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
с программированием на с++ я потихоньку забываю про логику, тут почему то мне все кажется совсем не логичным![Smile](images/smilies/new/smile.gif)
|