add new platform_abstraction
add support of loading ttf file
This commit is contained in:
parent
4aba8e8c7f
commit
2ff8a1c729
@ -49,7 +49,7 @@
|
||||
<Unit filename="../../source/charset.cpp" />
|
||||
<Unit filename="../../source/datetime.cpp" />
|
||||
<Unit filename="../../source/deploy.cpp" />
|
||||
<Unit filename="../../source/detail/platform_spec_posix.cpp" />
|
||||
<Unit filename="../../source/detail/platform_abstraction.cpp" />
|
||||
<Unit filename="../../source/detail/platform_spec_windows.cpp" />
|
||||
<Unit filename="../../source/filesystem/filesystem.cpp" />
|
||||
<Unit filename="../../source/gui/animation.cpp" />
|
||||
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_layout_file>
|
||||
<FileVersion major="1" minor="0" />
|
||||
<ActiveTarget name="Debug" />
|
||||
</CodeBlocks_layout_file>
|
@ -187,6 +187,7 @@
|
||||
<ClCompile Include="..\..\source\charset.cpp" />
|
||||
<ClCompile Include="..\..\source\datetime.cpp" />
|
||||
<ClCompile Include="..\..\source\deploy.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\platform_abstraction.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\platform_spec_windows.cpp" />
|
||||
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
|
||||
<ClCompile Include="..\..\source\gui\animation.cpp" />
|
||||
|
@ -330,6 +330,9 @@
|
||||
<ClCompile Include="..\..\source\gui\widgets\skeletons\content_view.cpp">
|
||||
<Filter>Source Files\nana\gui\widgets\skeletons</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\detail\platform_abstraction.cpp">
|
||||
<Filter>Source Files\nana\detail</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\gui\widgets\group.cpp">
|
||||
|
@ -181,6 +181,7 @@
|
||||
<ClCompile Include="..\..\source\charset.cpp" />
|
||||
<ClCompile Include="..\..\source\datetime.cpp" />
|
||||
<ClCompile Include="..\..\source\deploy.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\platform_abstraction.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\platform_spec_windows.cpp" />
|
||||
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
|
||||
<ClCompile Include="..\..\source\gui\animation.cpp" />
|
||||
|
@ -288,5 +288,8 @@
|
||||
<ClCompile Include="..\..\source\gui\widgets\skeletons\content_view.cpp">
|
||||
<Filter>Source Files\gui\widgets\skeletons</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\detail\platform_abstraction.cpp">
|
||||
<Filter>Source Files\detail</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -148,6 +148,7 @@
|
||||
<ClCompile Include="..\..\source\charset.cpp" />
|
||||
<ClCompile Include="..\..\source\datetime.cpp" />
|
||||
<ClCompile Include="..\..\source\deploy.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\platform_abstraction.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\platform_spec_windows.cpp" />
|
||||
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
|
||||
<ClCompile Include="..\..\source\gui\detail\basic_window.cpp" />
|
||||
|
@ -237,5 +237,8 @@
|
||||
<ClCompile Include="..\..\source\threads\pool.cpp">
|
||||
<Filter>源文件\threads</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\detail\platform_abstraction.cpp">
|
||||
<Filter>源文件\detail</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -116,6 +116,8 @@
|
||||
# define _enable_std_clamp
|
||||
# endif
|
||||
|
||||
#elif defined(NANA_MINGW)
|
||||
# define STD_THREAD_NOT_SUPPORTED
|
||||
#elif defined(__clang__) //Clang
|
||||
|
||||
#include <iosfwd> //Introduces some implement-specific flags of ISO C++ Library
|
||||
|
@ -435,7 +435,7 @@ namespace nana{ namespace widgets{ namespace skeletons
|
||||
};
|
||||
|
||||
::std::string font;
|
||||
std::size_t font_size;
|
||||
double font_size;
|
||||
bool bold;
|
||||
bool bold_empty; //bold should be ignored if bold_empty is true
|
||||
aligns::t text_align;
|
||||
|
29
include/nana/paint/detail/ptdefs.hpp
Normal file
29
include/nana/paint/detail/ptdefs.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef NANA_PAINT_PTDEFS_INCLUDED
|
||||
#define NANA_PAINT_PTDEFS_INCLUDED
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct native_font_signature;
|
||||
|
||||
|
||||
struct font_style
|
||||
{
|
||||
unsigned weight{ 400 }; //normal
|
||||
bool italic{ false };
|
||||
bool underline{ false };
|
||||
bool strike_out{ false };
|
||||
|
||||
font_style() = default;
|
||||
font_style(unsigned weight, bool italic = false, bool underline = false, bool strike_out = false);
|
||||
};
|
||||
}//end namespace detail
|
||||
|
||||
namespace paint
|
||||
{
|
||||
using native_font_type = ::nana::detail::native_font_signature*;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Paint Graphics Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -17,36 +17,45 @@
|
||||
|
||||
#include "../basic_types.hpp"
|
||||
#include "../gui/basis.hpp"
|
||||
#include <nana/filesystem/filesystem.hpp>
|
||||
|
||||
#include "detail/ptdefs.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct native_font_signature;
|
||||
}// end namespace detail
|
||||
|
||||
typedef detail::native_font_signature* native_font_type;
|
||||
|
||||
class font
|
||||
{
|
||||
friend class graphics;
|
||||
public:
|
||||
using path_type = ::std::experimental::filesystem::path;
|
||||
|
||||
using font_style = ::nana::detail::font_style;
|
||||
|
||||
font();
|
||||
font(drawable_type);
|
||||
font(const font&);
|
||||
font(const ::std::string& name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false);
|
||||
|
||||
font(const ::std::string& name, double size_pt, const font_style& fs = {});
|
||||
font(double size_pt, const path_type& truetype, const font_style& ft = {});
|
||||
|
||||
~font();
|
||||
bool empty() const;
|
||||
|
||||
/* //deprecated
|
||||
void make(const ::std::string& name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false);
|
||||
void make_raw(const ::std::string& name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out);
|
||||
|
||||
void make(const ::std::string& font_family, unsigned size, const font_style& fs = {});
|
||||
void make_from_ttf(const path_type& truetype, unsigned size, const font_style& fs = {});
|
||||
*/
|
||||
|
||||
void set_default() const;
|
||||
::std::string name() const;
|
||||
unsigned size() const;
|
||||
double size() const;
|
||||
bool bold() const;
|
||||
unsigned height() const;
|
||||
//unsigned height() const; //deprecated
|
||||
unsigned weight() const;
|
||||
bool italic() const;
|
||||
native_font_type handle() const;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <string.h>
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "detail/platform_spec_selector.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "../platform_abstraction_types.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
|
||||
@ -87,31 +89,16 @@ namespace detail
|
||||
};
|
||||
};
|
||||
|
||||
struct font_tag
|
||||
{
|
||||
native_string_type name;
|
||||
unsigned height;
|
||||
unsigned weight;
|
||||
bool italic;
|
||||
bool underline;
|
||||
bool strikeout;
|
||||
HFONT handle;
|
||||
|
||||
struct deleter
|
||||
{
|
||||
void operator()(const font_tag*) const;
|
||||
};
|
||||
};
|
||||
|
||||
struct drawable_impl_type
|
||||
{
|
||||
typedef std::shared_ptr<font_tag> font_ptr_t;
|
||||
using font_type = ::std::shared_ptr<font_interface>;
|
||||
|
||||
HDC context;
|
||||
HBITMAP pixmap;
|
||||
pixel_argb_t* pixbuf_ptr{nullptr};
|
||||
std::size_t bytes_per_line{0};
|
||||
font_ptr_t font;
|
||||
|
||||
font_type font;
|
||||
|
||||
struct pen_spec
|
||||
{
|
||||
@ -179,7 +166,6 @@ namespace detail
|
||||
platform_spec(platform_spec&&) = delete;
|
||||
platform_spec& operator=(platform_spec&&) = delete;
|
||||
public:
|
||||
typedef drawable_impl_type::font_ptr_t font_ptr_t;
|
||||
typedef ::nana::event_code event_code;
|
||||
typedef ::nana::native_window_type native_window_type;
|
||||
|
||||
@ -200,12 +186,6 @@ namespace detail
|
||||
|
||||
~platform_spec();
|
||||
|
||||
const font_ptr_t& default_native_font() const;
|
||||
void default_native_font(const font_ptr_t&);
|
||||
unsigned font_size_to_height(unsigned) const;
|
||||
unsigned font_height_to_size(unsigned) const;
|
||||
font_ptr_t make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out);
|
||||
|
||||
static platform_spec& instance();
|
||||
|
||||
void keep_window_icon(native_window_type, const paint::image&sml_icon, const paint::image& big_icon);
|
409
source/detail/platform_abstraction.cpp
Normal file
409
source/detail/platform_abstraction.cpp
Normal file
@ -0,0 +1,409 @@
|
||||
#include "platform_abstraction.hpp"
|
||||
#include <nana/deploy.hpp>
|
||||
#include "../paint/truetype.hpp"
|
||||
|
||||
#ifdef NANA_WINDOWS
|
||||
# include <windows.h>
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************************************************
|
||||
* *
|
||||
* VersionHelpers.h -- This module defines helper functions to *
|
||||
* promote version check with proper *
|
||||
* comparisons. *
|
||||
* *
|
||||
* Copyright (c) Microsoft Corp. All rights reserved. *
|
||||
* *
|
||||
******************************************************************/
|
||||
|
||||
#include <specstrings.h> // for _In_, etc.
|
||||
|
||||
#if !defined(__midl) && !defined(SORTPP_PASS)
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#define VERSIONHELPERAPI inline bool
|
||||
|
||||
#else // __cplusplus
|
||||
|
||||
#define VERSIONHELPERAPI FORCEINLINE BOOL
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 };
|
||||
DWORDLONG const dwlConditionMask = VerSetConditionMask(
|
||||
VerSetConditionMask(
|
||||
VerSetConditionMask(
|
||||
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
|
||||
VER_MINORVERSION, VER_GREATER_EQUAL),
|
||||
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
|
||||
osvi.dwMajorVersion = wMajorVersion;
|
||||
osvi.dwMinorVersion = wMinorVersion;
|
||||
osvi.wServicePackMajor = wServicePackMajor;
|
||||
|
||||
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsXPOrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsXPSP1OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsXPSP2OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsXPSP3OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsVistaOrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsVistaSP1OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsVistaSP2OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindows7OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindows7SP1OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WINNT_WIN8 // (0x0602)
|
||||
#define _WIN32_WINNT_WIN8 (0x0602)
|
||||
#endif // _WIN32_WINNT_WIN8(0x0602)
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindows8OrGreater()
|
||||
{
|
||||
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WINNT_WINBLUE // (0x0602)
|
||||
#define _WIN32_WINNT_WINBLUE (0x0602)
|
||||
#endif // _WIN32_WINNT_WINBLUE (0x0602)
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindows8Point1OrGreater()
|
||||
{
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
|
||||
}
|
||||
|
||||
VERSIONHELPERAPI
|
||||
IsWindowsServer()
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0, 0, VER_NT_WORKSTATION };
|
||||
DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
|
||||
|
||||
return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
|
||||
}
|
||||
|
||||
#endif // NTDDI_VERSION
|
||||
|
||||
#endif // defined(__midl)
|
||||
#else
|
||||
# include "posix/platform_spec.hpp"
|
||||
# include <fontconfig/fontconfig.h>
|
||||
# if defined(NANA_USE_XFT)
|
||||
# include <X11/Xft/Xft.h>
|
||||
# include <iconv.h>
|
||||
# include <fstream>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
|
||||
class internal_font
|
||||
: public font_interface
|
||||
{
|
||||
public:
|
||||
using path_type = std::experimental::filesystem::path;
|
||||
|
||||
internal_font(const path_type& ttf, const std::string& font_family, double font_size, const font_style& fs, native_font_type native_font):
|
||||
ttf_(ttf),
|
||||
family_(font_family),
|
||||
size_(font_size),
|
||||
style_(fs),
|
||||
native_handle_(native_font)
|
||||
{}
|
||||
|
||||
~internal_font()
|
||||
{
|
||||
#ifdef NANA_WINDOWS
|
||||
::DeleteObject(reinterpret_cast<HFONT>(native_handle_));
|
||||
#elif defined(NANA_X11)
|
||||
auto disp = ::nana::detail::platform_spec::instance().open_display();
|
||||
# ifdef NANA_USE_XFT
|
||||
::XftFontClose(disp, reinterpret_cast<XftFont*>(native_handle_));
|
||||
# else
|
||||
::XFreeFontSet(disp, reinterpret_cast<XFontSet>(native_handle_));
|
||||
# endif
|
||||
#endif
|
||||
if (!ttf_.empty())
|
||||
platform_abstraction::font_resource(false, ttf_);
|
||||
}
|
||||
public:
|
||||
const std::string& family() const override
|
||||
{
|
||||
return family_;
|
||||
}
|
||||
|
||||
double size() const override
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
const font_style & style() const override
|
||||
{
|
||||
return style_;
|
||||
}
|
||||
|
||||
native_font_type native_handle() const override
|
||||
{
|
||||
return native_handle_;
|
||||
}
|
||||
private:
|
||||
path_type const ttf_;
|
||||
std::string const family_;
|
||||
double const size_;
|
||||
font_style const style_;
|
||||
native_font_type const native_handle_;
|
||||
};
|
||||
|
||||
struct platform_runtime
|
||||
{
|
||||
std::shared_ptr<font_interface> font;
|
||||
|
||||
#ifdef NANA_X11
|
||||
std::map<std::string, std::size_t> fontconfig_counts;
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
static platform_runtime* storage;
|
||||
}
|
||||
}
|
||||
|
||||
static platform_runtime& platform_storage()
|
||||
{
|
||||
if (nullptr == data::storage)
|
||||
throw std::runtime_error("platform_abstraction is empty");
|
||||
|
||||
return *data::storage;
|
||||
}
|
||||
|
||||
void platform_abstraction::initialize()
|
||||
{
|
||||
if (nullptr == data::storage)
|
||||
data::storage = new platform_runtime;
|
||||
}
|
||||
|
||||
void platform_abstraction::shutdown()
|
||||
{
|
||||
auto & r = platform_storage();
|
||||
|
||||
if (r.font.use_count() > 1)
|
||||
throw std::runtime_error("platform_abstraction is disallowed to shutdown");
|
||||
|
||||
r.font.reset();
|
||||
|
||||
delete data::storage;
|
||||
data::storage = nullptr;
|
||||
}
|
||||
|
||||
::std::shared_ptr<platform_abstraction::font> platform_abstraction::default_font(const ::std::shared_ptr<font>& new_font)
|
||||
{
|
||||
auto & r = platform_storage();
|
||||
if (new_font)
|
||||
{
|
||||
auto f = r.font;
|
||||
if (new_font != r.font)
|
||||
r.font = new_font;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
if (!r.font)
|
||||
r.font = make_font({}, 0, {});
|
||||
|
||||
return r.font;
|
||||
}
|
||||
|
||||
static std::shared_ptr<platform_abstraction::font> font_factory(::std::string font_family, double size_pt, const platform_abstraction::font::font_style& fs, internal_font::path_type ttf)
|
||||
{
|
||||
using native_font_type = platform_abstraction::font::native_font_type;
|
||||
#ifdef NANA_WINDOWS
|
||||
std::wstring wfont_family = to_nstring(font_family);
|
||||
|
||||
//Make sure the length of font family less than LF_FACESIZE which is defined by Windows
|
||||
if (wfont_family.length() + 1 > LF_FACESIZE)
|
||||
wfont_family.clear();
|
||||
|
||||
//Translate pt to px
|
||||
auto hDC = ::GetDC(nullptr);
|
||||
auto font_height = -static_cast<LONG>(size_pt * ::GetDeviceCaps(hDC, LOGPIXELSY) / 72);
|
||||
::ReleaseDC(nullptr, hDC);
|
||||
|
||||
if (wfont_family.empty() || (0 == font_height))
|
||||
{
|
||||
//Create default font object.
|
||||
NONCLIENTMETRICS metrics = {};
|
||||
metrics.cbSize = sizeof metrics;
|
||||
#if(WINVER >= 0x0600)
|
||||
#if defined(NANA_MINGW)
|
||||
OSVERSIONINFO osvi = {};
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
::GetVersionEx(&osvi);
|
||||
if (osvi.dwMajorVersion < 6)
|
||||
metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth);
|
||||
#else
|
||||
if (!IsWindowsVistaOrGreater())
|
||||
metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth);
|
||||
#endif
|
||||
#endif
|
||||
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0);
|
||||
|
||||
if (wfont_family.empty())
|
||||
{
|
||||
wfont_family = metrics.lfMessageFont.lfFaceName;
|
||||
font_family = to_utf8(wfont_family);
|
||||
}
|
||||
|
||||
if (0 == font_height)
|
||||
font_height = metrics.lfMessageFont.lfHeight;
|
||||
}
|
||||
|
||||
|
||||
::LOGFONT lf{};
|
||||
|
||||
std::wcscpy(lf.lfFaceName, wfont_family.c_str());
|
||||
lf.lfHeight = font_height;
|
||||
lf.lfCharSet = DEFAULT_CHARSET;
|
||||
lf.lfWeight = fs.weight;
|
||||
lf.lfQuality = PROOF_QUALITY;
|
||||
lf.lfPitchAndFamily = FIXED_PITCH;
|
||||
lf.lfItalic = fs.italic;
|
||||
lf.lfUnderline = fs.underline;
|
||||
lf.lfStrikeOut = fs.strike_out;
|
||||
|
||||
auto fd = ::CreateFontIndirect(&lf);
|
||||
#elif defined(NANA_X11)
|
||||
auto disp = ::nana::detail::platform_spec::instance().open_display();
|
||||
# ifdef NANA_USE_XFT
|
||||
if(font_family.empty())
|
||||
font_family = '*';
|
||||
|
||||
std::string pat_str = font_family + '-' + std::to_string(size_pt ? size_pt : 10);
|
||||
auto pat = ::XftNameParse(pat_str.c_str());
|
||||
XftResult res;
|
||||
auto match_pat = ::XftFontMatch(disp, ::XDefaultScreen(disp), pat, &res);
|
||||
|
||||
::XftFont* fd = nullptr;
|
||||
if (match_pat)
|
||||
fd = ::XftFontOpenPattern(disp, match_pat);
|
||||
# else
|
||||
std::string pat_str;
|
||||
if (font_family.empty())
|
||||
pat_str = "-misc-fixed-*";
|
||||
else
|
||||
pat_str = "-misc-fixed-" + font_family;
|
||||
|
||||
char ** missing_list;
|
||||
int missing_count;
|
||||
char * defstr;
|
||||
XFontSet fd = ::XCreateFontSet(display_, const_cast<char*>(pat_str.c_str()), &missing_list, &missing_count, &defstr);
|
||||
# endif
|
||||
#endif
|
||||
if (fd)
|
||||
return std::make_shared<internal_font>(std::move(ttf), std::move(font_family), size_pt, fs, reinterpret_cast<native_font_type>(fd));
|
||||
return{};
|
||||
}
|
||||
|
||||
::std::shared_ptr<platform_abstraction::font> platform_abstraction::make_font(const std::string& font_family, double size_pt, const font::font_style& fs)
|
||||
{
|
||||
return font_factory(font_family, size_pt, fs, {});
|
||||
}
|
||||
|
||||
::std::shared_ptr<platform_abstraction::font> platform_abstraction::make_font_from_ttf(const path_type& ttf, double size_pt, const font::font_style& fs)
|
||||
{
|
||||
::nana::spec::truetype truetype{ ttf };
|
||||
if (truetype.font_family().empty())
|
||||
return nullptr;
|
||||
|
||||
font_resource(true, ttf);
|
||||
|
||||
return font_factory(truetype.font_family(), size_pt, fs, ttf);
|
||||
}
|
||||
|
||||
void platform_abstraction::font_resource(bool try_add, const path_type& ttf)
|
||||
{
|
||||
#ifdef NANA_WINDOWS
|
||||
if (try_add)
|
||||
::AddFontResourceEx(ttf.wstring().c_str(), FR_PRIVATE, nullptr);
|
||||
else
|
||||
::RemoveFontResourceEx(ttf.wstring().c_str(), FR_PRIVATE, nullptr);
|
||||
#else
|
||||
auto & fc = platform_storage().fontconfig_counts;
|
||||
if(try_add)
|
||||
{
|
||||
if(1 == ++(fc[ttf.string()]))
|
||||
{
|
||||
auto state = ::FcConfigAppFontAddFile(nullptr, reinterpret_cast<const FcChar8*>(ttf.string().c_str()));
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto i = fc.find(ttf.string());
|
||||
if(i != fc.end())
|
||||
{
|
||||
if(0 == --(i->second))
|
||||
fc.erase(i);
|
||||
|
||||
if(0 == fc.size())
|
||||
::FcConfigAppFontClear(nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
43
source/detail/platform_abstraction.hpp
Normal file
43
source/detail/platform_abstraction.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Platform Abstraction
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/detail/platform_spec.hpp
|
||||
*
|
||||
* The platform_abstraction provides some functions and types for the abstract
|
||||
* system platform.
|
||||
*/
|
||||
#ifndef NANA_DETAIL_PLATFORM_ABSTRACTION_HEADER_INCLUDED
|
||||
#define NANA_DETAIL_PLATFORM_ABSTRACTION_HEADER_INCLUDED
|
||||
|
||||
#include "platform_abstraction_types.hpp"
|
||||
#include <memory>
|
||||
#include <nana/filesystem/filesystem.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
|
||||
|
||||
class platform_abstraction
|
||||
{
|
||||
public:
|
||||
using font = font_interface;
|
||||
|
||||
using path_type = ::std::experimental::filesystem::path;
|
||||
|
||||
static void initialize();
|
||||
/// Shutdown before destruction of platform_spec
|
||||
static void shutdown();
|
||||
static ::std::shared_ptr<font> default_font(const ::std::shared_ptr<font>&);
|
||||
static ::std::shared_ptr<font> make_font(const ::std::string& font_family, double size_pt, const font::font_style& fs);
|
||||
static ::std::shared_ptr<font> make_font_from_ttf(const path_type& ttf, double size_pt, const font::font_style& fs);
|
||||
static void font_resource(bool try_add, const path_type& ttf);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
29
source/detail/platform_abstraction_types.hpp
Normal file
29
source/detail/platform_abstraction_types.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef NANA_DETAIL_PLATFORM_ABSTRACTION_TYPES_HEADER_INCLUDED
|
||||
#define NANA_DETAIL_PLATFORM_ABSTRACTION_TYPES_HEADER_INCLUDED
|
||||
#include <nana/config.hpp>
|
||||
#include <nana/paint/detail/ptdefs.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef NANA_X11
|
||||
# define NANA_USE_XFT
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class font_interface
|
||||
{
|
||||
public:
|
||||
using font_style = detail::font_style;
|
||||
using native_font_type = paint::native_font_type;
|
||||
|
||||
virtual ~font_interface() = default;
|
||||
|
||||
virtual const std::string& family() const = 0;
|
||||
virtual double size() const = 0;
|
||||
virtual const font_style & style() const = 0;
|
||||
virtual native_font_type native_handle() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -14,7 +14,8 @@
|
||||
* http://standards.freedesktop.org/clipboards-spec/clipboards-0.1.txt
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "platform_spec_selector.hpp"
|
||||
#include "platform_abstraction.hpp"
|
||||
#if defined(NANA_POSIX) && defined(NANA_X11)
|
||||
|
||||
#include <nana/push_ignore_diagnostic>
|
||||
@ -33,7 +34,7 @@
|
||||
#include <errno.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "x11/msg_dispatcher.hpp"
|
||||
#include "posix/msg_dispatcher.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
@ -451,24 +452,6 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
class font_deleter
|
||||
{
|
||||
public:
|
||||
void operator()(const font_tag* fp) const
|
||||
{
|
||||
if(fp && fp->handle)
|
||||
{
|
||||
platform_scope_guard psg;
|
||||
#if defined(NANA_USE_XFT)
|
||||
::XftFontClose(nana::detail::platform_spec::instance().open_display(), fp->handle);
|
||||
#else
|
||||
::XFreeFontSet(nana::detail::platform_spec::instance().open_display(), fp->handle);
|
||||
#endif
|
||||
}
|
||||
delete fp;
|
||||
}
|
||||
};//end class font_deleter
|
||||
|
||||
platform_scope_guard::platform_scope_guard()
|
||||
{
|
||||
platform_spec::instance().lock_xlib();
|
||||
@ -561,9 +544,9 @@ namespace detail
|
||||
atombase_.xdnd_typelist = ::XInternAtom(display_, "XdndTypeList", False);
|
||||
atombase_.xdnd_finished = ::XInternAtom(display_, "XdndFinished", False);
|
||||
|
||||
//Create default font object.
|
||||
def_font_ptr_ = make_native_font(nullptr, font_size_to_height(10), 400, false, false, false);
|
||||
msg_dispatcher_ = new msg_dispatcher(display_);
|
||||
|
||||
platform_abstraction::initialize();
|
||||
}
|
||||
|
||||
platform_spec::~platform_spec()
|
||||
@ -572,75 +555,11 @@ namespace detail
|
||||
|
||||
//The font should be destroyed before closing display,
|
||||
//otherwise it crashs
|
||||
def_font_ptr_.reset();
|
||||
platform_abstraction::shutdown();
|
||||
|
||||
close_display();
|
||||
}
|
||||
|
||||
const platform_spec::font_ptr_t& platform_spec::default_native_font() const
|
||||
{
|
||||
return def_font_ptr_;
|
||||
}
|
||||
|
||||
void platform_spec::default_native_font(const font_ptr_t& fp)
|
||||
{
|
||||
def_font_ptr_ = fp;
|
||||
}
|
||||
|
||||
unsigned platform_spec::font_size_to_height(unsigned size) const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned platform_spec::font_height_to_size(unsigned height) const
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
platform_spec::font_ptr_t platform_spec::make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out)
|
||||
{
|
||||
font_ptr_t ref;
|
||||
#if 1 //Xft
|
||||
if(0 == name || *name == 0)
|
||||
name = "*";
|
||||
|
||||
XftFont* handle = 0;
|
||||
std::stringstream ss;
|
||||
ss<<name<<"-"<<(height ? height : 10);
|
||||
XftPattern * pat = ::XftNameParse(ss.str().c_str());
|
||||
XftResult res;
|
||||
XftPattern * match_pat = ::XftFontMatch(display_, ::XDefaultScreen(display_), pat, &res);
|
||||
if(match_pat)
|
||||
handle = ::XftFontOpenPattern(display_, match_pat);
|
||||
#else
|
||||
std::string basestr;
|
||||
if(0 == name || *name == 0)
|
||||
{
|
||||
basestr = "-misc-fixed-*";
|
||||
}
|
||||
else
|
||||
basestr = "-misc-fixed-*";
|
||||
|
||||
char ** missing_list;
|
||||
int missing_count;
|
||||
char * defstr;
|
||||
XFontSet handle = ::XCreateFontSet(display_, const_cast<char*>(basestr.c_str()), &missing_list, &missing_count, &defstr);
|
||||
#endif
|
||||
if(handle)
|
||||
{
|
||||
font_tag * impl = new font_tag;
|
||||
impl->name = name;
|
||||
impl->height = height;
|
||||
impl->weight = weight;
|
||||
impl->italic = italic;
|
||||
impl->underline = underline;
|
||||
impl->strikeout = strike_out;
|
||||
impl->handle = handle;
|
||||
return font_ptr_t(impl, font_deleter());
|
||||
}
|
||||
return font_ptr_t();
|
||||
}
|
||||
|
||||
Display* platform_spec::open_display()
|
||||
{
|
||||
return display_;
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <nana/config.hpp>
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <nana/detail/win32/platform_spec.hpp>
|
||||
#include "mswin/platform_spec.hpp"
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <nana/detail/linux_X11/platform_spec.hpp>
|
||||
#include "posix/platform_spec.hpp"
|
||||
#endif
|
@ -12,15 +12,18 @@
|
||||
* @brief basis classes and data structures required by nana
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "platform_spec_selector.hpp"
|
||||
#include "platform_abstraction.hpp"
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************************************************
|
||||
@ -310,15 +313,6 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
//struct font_tag::deleter
|
||||
void font_tag::deleter::operator()(const font_tag* tag) const
|
||||
{
|
||||
if(tag && tag->handle)
|
||||
::DeleteObject(tag->handle);
|
||||
delete tag;
|
||||
}
|
||||
//end struct font_tag::deleter
|
||||
|
||||
//class platform_spec
|
||||
platform_spec::co_initializer::co_initializer()
|
||||
: ole32_(::LoadLibrary(L"OLE32.DLL"))
|
||||
@ -354,104 +348,21 @@ namespace detail
|
||||
|
||||
struct platform_spec::implementation
|
||||
{
|
||||
font_ptr_t def_font_ptr;
|
||||
std::map<native_window_type, window_icons> iconbase;
|
||||
};
|
||||
|
||||
platform_spec::platform_spec()
|
||||
: impl_{ new implementation}
|
||||
{
|
||||
//Create default font object.
|
||||
NONCLIENTMETRICS metrics = {};
|
||||
metrics.cbSize = sizeof metrics;
|
||||
#if(WINVER >= 0x0600)
|
||||
#if defined(NANA_MINGW)
|
||||
OSVERSIONINFO osvi = {};
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
::GetVersionEx(&osvi);
|
||||
if (osvi.dwMajorVersion < 6)
|
||||
metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth);
|
||||
#else
|
||||
if(!IsWindowsVistaOrGreater())
|
||||
metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth);
|
||||
#endif
|
||||
#endif
|
||||
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0);
|
||||
impl_->def_font_ptr = make_native_font(to_utf8(metrics.lfMessageFont.lfFaceName).c_str(), font_size_to_height(9), 400, false, false, false);
|
||||
platform_abstraction::initialize();
|
||||
}
|
||||
|
||||
platform_spec::~platform_spec()
|
||||
{
|
||||
platform_abstraction::shutdown();
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
const platform_spec::font_ptr_t& platform_spec::default_native_font() const
|
||||
{
|
||||
return impl_->def_font_ptr;
|
||||
}
|
||||
|
||||
void platform_spec::default_native_font(const font_ptr_t& fp)
|
||||
{
|
||||
impl_->def_font_ptr = fp;
|
||||
}
|
||||
|
||||
unsigned platform_spec::font_size_to_height(unsigned size) const
|
||||
{
|
||||
HDC hdc = ::GetDC(0);
|
||||
size = ::MulDiv(int(size), ::GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
||||
::ReleaseDC(0, hdc);
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned platform_spec::font_height_to_size(unsigned height) const
|
||||
{
|
||||
HDC hdc = ::GetDC(0);
|
||||
unsigned pixels = ::GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
::ReleaseDC(0, hdc);
|
||||
|
||||
height = static_cast<unsigned>(static_cast<long long>(72) * height / pixels);
|
||||
return height;
|
||||
}
|
||||
|
||||
platform_spec::font_ptr_t platform_spec::make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out)
|
||||
{
|
||||
::LOGFONT logfont;
|
||||
memset(&logfont, 0, sizeof logfont);
|
||||
|
||||
if (name && *name)
|
||||
std::wcscpy(logfont.lfFaceName, to_wstring(name).c_str());
|
||||
else
|
||||
std::wcscpy(logfont.lfFaceName, impl_->def_font_ptr->name.c_str());
|
||||
|
||||
logfont.lfCharSet = DEFAULT_CHARSET;
|
||||
HDC hdc = ::GetDC(0);
|
||||
logfont.lfHeight = -static_cast<int>(height);
|
||||
::ReleaseDC(0, hdc);
|
||||
|
||||
logfont.lfWidth = 0;
|
||||
logfont.lfWeight = weight;
|
||||
logfont.lfQuality = PROOF_QUALITY;
|
||||
logfont.lfPitchAndFamily = FIXED_PITCH;
|
||||
logfont.lfItalic = italic;
|
||||
logfont.lfUnderline = underline;
|
||||
logfont.lfStrikeOut = strike_out;
|
||||
HFONT result = ::CreateFontIndirect(&logfont);
|
||||
|
||||
if(result)
|
||||
{
|
||||
font_tag * impl = new font_tag;
|
||||
impl->name = logfont.lfFaceName;
|
||||
impl->height = height;
|
||||
impl->weight = weight;
|
||||
impl->italic = italic;
|
||||
impl->underline = underline;
|
||||
impl->strikeout = strike_out;
|
||||
impl->handle = result;
|
||||
return std::shared_ptr<font_tag>(impl, font_tag::deleter());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
platform_spec& platform_spec::instance()
|
||||
{
|
||||
static platform_spec object;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#ifndef NANA_DETAIL_MSG_DISPATCHER_HPP
|
||||
#define NANA_DETAIL_MSG_DISPATCHER_HPP
|
||||
#include <nana/detail/linux_X11/msg_packet.hpp>
|
||||
#include "msg_packet.hpp"
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <list>
|
||||
#include <set>
|
@ -36,8 +36,8 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "msg_packet.hpp"
|
||||
#include "../platform_abstraction_types.hpp"
|
||||
|
||||
#define NANA_USE_XFT
|
||||
#if defined(NANA_USE_XFT)
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <iconv.h>
|
||||
@ -49,6 +49,7 @@ namespace nana
|
||||
namespace detail
|
||||
{
|
||||
class msg_dispatcher;
|
||||
|
||||
#if defined(NANA_USE_XFT)
|
||||
class conf
|
||||
{
|
||||
@ -74,28 +75,14 @@ namespace detail
|
||||
};
|
||||
#endif
|
||||
|
||||
struct font_tag
|
||||
{
|
||||
std::string name;
|
||||
unsigned height;
|
||||
unsigned weight;
|
||||
bool italic;
|
||||
bool underline;
|
||||
bool strikeout;
|
||||
#if defined(NANA_USE_XFT)
|
||||
XftFont * handle;
|
||||
#else
|
||||
XFontSet handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct drawable_impl_type
|
||||
{
|
||||
typedef std::shared_ptr<font_tag> font_ptr_t;
|
||||
using font_type = ::std::shared_ptr<font_interface>;
|
||||
|
||||
Pixmap pixmap;
|
||||
GC context;
|
||||
font_ptr_t font;
|
||||
|
||||
font_type font;
|
||||
|
||||
nana::point line_begin_pos;
|
||||
|
||||
@ -105,6 +92,7 @@ namespace detail
|
||||
unsigned tab_pixels;
|
||||
unsigned whitespace_pixels;
|
||||
}string;
|
||||
|
||||
#if defined(NANA_USE_XFT)
|
||||
XftDraw * xftdraw{nullptr};
|
||||
XftColor xft_fgcolor;
|
||||
@ -199,7 +187,6 @@ namespace detail
|
||||
public:
|
||||
int error_code;
|
||||
public:
|
||||
typedef drawable_impl_type::font_ptr_t font_ptr_t;
|
||||
typedef void (*timer_proc_type)(unsigned tid);
|
||||
typedef void (*event_proc_type)(Display*, msg_packet_tag&);
|
||||
typedef ::nana::event_code event_code;
|
||||
@ -211,12 +198,6 @@ namespace detail
|
||||
platform_spec();
|
||||
~platform_spec();
|
||||
|
||||
const font_ptr_t& default_native_font() const;
|
||||
void default_native_font(const font_ptr_t&);
|
||||
unsigned font_size_to_height(unsigned) const;
|
||||
unsigned font_height_to_size(unsigned) const;
|
||||
font_ptr_t make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strick_out);
|
||||
|
||||
Display* open_display();
|
||||
void close_display();
|
||||
|
||||
@ -277,7 +258,7 @@ namespace detail
|
||||
Display* display_;
|
||||
Colormap colormap_;
|
||||
atombase_tag atombase_;
|
||||
font_ptr_t def_font_ptr_;
|
||||
|
||||
XKeyEvent key_state_;
|
||||
int (*def_X11_error_handler_)(Display*, XErrorEvent*);
|
||||
Window grab_;
|
@ -10,7 +10,7 @@
|
||||
* @file: nana/gui/detail/bedrock_pi.cpp
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../../detail/platform_spec_selector.hpp"
|
||||
#include <nana/gui/detail/bedrock_pi_data.hpp>
|
||||
#include <nana/gui/detail/event_code.hpp>
|
||||
#include <nana/system/platform.hpp>
|
||||
|
@ -10,7 +10,7 @@
|
||||
* @file: nana/gui/detail/linux_X11/bedrock.cpp
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../../detail/platform_spec_selector.hpp"
|
||||
#if defined(NANA_POSIX) && defined(NANA_X11)
|
||||
#include <nana/gui/detail/bedrock_pi_data.hpp>
|
||||
#include <nana/gui/detail/event_code.hpp>
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @contributors: Ariel Vina-Rodriguez
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../../detail/platform_spec_selector.hpp"
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <nana/gui/detail/bedrock.hpp>
|
||||
#include <nana/gui/detail/bedrock_pi_data.hpp>
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "dynamic_drawing_object.hpp"
|
||||
|
||||
#if defined(NANA_X11)
|
||||
#include <nana/detail/linux_X11/platform_spec.hpp>
|
||||
#include "../../detail/posix/platform_spec.hpp"
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
|
@ -10,7 +10,7 @@
|
||||
* @file: nana/gui/detail/native_window_interface.cpp
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../../detail/platform_spec_selector.hpp"
|
||||
#include <nana/gui/detail/native_window_interface.hpp>
|
||||
#include <nana/gui/screen.hpp>
|
||||
#include <nana/gui/detail/bedrock.hpp>
|
||||
|
@ -1397,13 +1397,13 @@ namespace detail
|
||||
{
|
||||
auto & tabs = wd->root_widget->other.attribute.root->tabstop;
|
||||
|
||||
auto end = tabs.cend();
|
||||
if (forward)
|
||||
{
|
||||
if (detail::tab_type::none == wd->flags.tab)
|
||||
return (tabs.front());
|
||||
else if (detail::tab_type::tabstop & wd->flags.tab)
|
||||
{
|
||||
auto end = tabs.cend();
|
||||
auto i = std::find(tabs.cbegin(), end, wd);
|
||||
if (i != end)
|
||||
{
|
||||
@ -1417,8 +1417,8 @@ namespace detail
|
||||
}
|
||||
else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward.
|
||||
{
|
||||
auto i = std::find(tabs.cbegin(), tabs.cend(), wd);
|
||||
if (i != tabs.cend())
|
||||
auto i = std::find(tabs.cbegin(), end, wd);
|
||||
if (i != end)
|
||||
return (tabs.cbegin() == i ? tabs.back() : *(i - 1));
|
||||
}
|
||||
return nullptr;
|
||||
@ -1729,7 +1729,7 @@ namespace detail
|
||||
|
||||
if (established)
|
||||
{
|
||||
utl::erase(pa_children, wd);
|
||||
utl::erase(wd->parent->children, wd);
|
||||
if (for_new->children.empty())
|
||||
wd->index = 0;
|
||||
else
|
||||
@ -1892,15 +1892,20 @@ namespace detail
|
||||
if(!wd->visible)
|
||||
return nullptr;
|
||||
|
||||
for(auto i = wd->children.rbegin(); i != wd->children.rend(); ++i)
|
||||
if (!wd->children.empty())
|
||||
{
|
||||
core_window_t* child = *i;
|
||||
if((child->other.category != category::flags::root) && _m_effective(child, pos))
|
||||
auto index = wd->children.size();
|
||||
|
||||
do
|
||||
{
|
||||
child = _m_find(child, pos);
|
||||
if(child)
|
||||
return child;
|
||||
}
|
||||
auto child = wd->children[--index];
|
||||
if ((child->other.category != category::flags::root) && _m_effective(child, pos))
|
||||
{
|
||||
child = _m_find(child, pos);
|
||||
if (child)
|
||||
return child;
|
||||
}
|
||||
} while (0 != index);
|
||||
}
|
||||
return wd;
|
||||
}
|
||||
|
@ -133,9 +133,10 @@ namespace nana
|
||||
if (base_.erase(wd))
|
||||
{
|
||||
wdcache_.insert(wd, false);
|
||||
trash_.push_back(wd);
|
||||
|
||||
if (category::flags::root == wd->other.category)
|
||||
{
|
||||
trash_.push_back(wd);
|
||||
auto i = std::find(queue_.begin(), queue_.end(), wd);
|
||||
if (i != queue_.end())
|
||||
queue_.erase(i);
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <nana/system/platform.hpp>
|
||||
|
@ -28,7 +28,7 @@
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
#include <nana/system/platform.hpp>
|
||||
#endif
|
||||
|
||||
|
@ -117,10 +117,10 @@ namespace nana
|
||||
|
||||
if((tv != align_v::top) && extent_v_pixels < graph.height())
|
||||
{
|
||||
rs.pos.y = static_cast<int>(graph.height() - extent_v_pixels);
|
||||
|
||||
if(align_v::center == tv)
|
||||
rs.pos.y = static_cast<int>(graph.height() - extent_v_pixels) >> 1;
|
||||
else if(align_v::bottom == tv)
|
||||
rs.pos.y = static_cast<int>(graph.height() - extent_v_pixels);
|
||||
rs.pos.y >>= 1;
|
||||
}
|
||||
else
|
||||
rs.pos.y = 0;
|
||||
@ -203,7 +203,7 @@ namespace nana
|
||||
}
|
||||
private:
|
||||
//Manage the fblock for a specified rectangle if it is a traceable fblock.
|
||||
void _m_inser_if_traceable(int x, int y, const nana::size& sz, widgets::skeletons::fblock* fbp)
|
||||
void _m_insert_if_traceable(int x, int y, const nana::size& sz, widgets::skeletons::fblock* fbp)
|
||||
{
|
||||
if(fbp->target.size() || fbp->url.size())
|
||||
{
|
||||
@ -236,9 +236,9 @@ namespace nana
|
||||
return fp->fgcolor;
|
||||
}
|
||||
|
||||
std::size_t _m_font_size(nana::widgets::skeletons::fblock* fp) noexcept
|
||||
double _m_font_size(nana::widgets::skeletons::fblock* fp) noexcept
|
||||
{
|
||||
while(fp->font_size == 0xFFFFFFFF)
|
||||
while(fp->font_size == -1)
|
||||
{
|
||||
fp = fp->parent;
|
||||
if(nullptr == fp)
|
||||
@ -274,12 +274,14 @@ namespace nana
|
||||
if(fp != fblock_)
|
||||
{
|
||||
auto& name = _m_fontname(fp);
|
||||
auto fontsize = static_cast<unsigned>(_m_font_size(fp));
|
||||
auto fontsize = _m_font_size(fp);
|
||||
bool bold = _m_bold(fp);
|
||||
|
||||
if((fontsize != font_.size()) || bold != font_.bold() || name != font_.name())
|
||||
{
|
||||
font_.make(name, fontsize, bold);
|
||||
paint::font::font_style fs;
|
||||
fs.weight = (bold ? 800 : 400);
|
||||
font_ = paint::font{ name, fontsize, fs };
|
||||
graph.typeface(font_);
|
||||
}
|
||||
fblock_ = fp;
|
||||
@ -345,7 +347,7 @@ namespace nana
|
||||
|
||||
std::vector<iterator> line_values;
|
||||
|
||||
for(auto i = line.begin(), end = line.end(); i != end; ++i)
|
||||
for(auto i = line.begin(); i != line.end(); ++i)
|
||||
{
|
||||
data * data_ptr = i->data_ptr;
|
||||
nana::size sz = data_ptr->size();
|
||||
@ -378,12 +380,11 @@ namespace nana
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel_tag px;
|
||||
_m_align_x_base(rs, px, (w ? w : sz.width));
|
||||
|
||||
if(w)
|
||||
{
|
||||
pixel_tag px;
|
||||
|
||||
_m_align_x_base(rs, px, w);
|
||||
|
||||
if(max_ascent + max_descent > max_px)
|
||||
max_px = max_descent + max_ascent;
|
||||
else
|
||||
@ -393,8 +394,6 @@ namespace nana
|
||||
px.baseline = max_ascent;
|
||||
px.values.swap(line_values);
|
||||
|
||||
rs.pixels.emplace_back(px);
|
||||
|
||||
w = sz.width;
|
||||
max_px = sz.height;
|
||||
max_ascent = as;
|
||||
@ -403,18 +402,16 @@ namespace nana
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel_tag px;
|
||||
|
||||
_m_align_x_base(rs, px, sz.width);
|
||||
px.pixels = sz.height;
|
||||
px.baseline = as;
|
||||
|
||||
px.values.emplace_back(i);
|
||||
|
||||
rs.pixels.emplace_back(px);
|
||||
max_px = 0;
|
||||
max_ascent = max_descent = 0;
|
||||
}
|
||||
|
||||
rs.pixels.emplace_back(px);
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,49 +441,48 @@ namespace nana
|
||||
|
||||
const int lastpos = static_cast<int>(graph.height()) - 1;
|
||||
|
||||
for(auto i = rs.pixels.begin(), end = rs.pixels.end(); i != end; ++i)
|
||||
for(auto & px : rs.pixels)
|
||||
{
|
||||
for (auto & render_iterator : i->values)
|
||||
for(auto & render_iterator: px.values)
|
||||
{
|
||||
auto & value = *render_iterator;
|
||||
if(false == value.data_ptr->is_text())
|
||||
{
|
||||
if(text.size())
|
||||
{
|
||||
_m_draw_block(graph, text, block_start, rs);
|
||||
if(lastpos <= rs.pos.y)
|
||||
return false;
|
||||
text.clear();
|
||||
}
|
||||
nana::size sz = value.data_ptr->size();
|
||||
|
||||
pixel_tag px = rs.pixels[rs.index];
|
||||
if ((rs.allowed_width < rs.pos.x + sz.width) && (rs.pos.x != px.x_base))
|
||||
{
|
||||
//Change a line.
|
||||
rs.pos.y += static_cast<int>(px.pixels);
|
||||
px = rs.pixels[++rs.index];
|
||||
rs.pos.x = px.x_base;
|
||||
}
|
||||
|
||||
int y = rs.pos.y + _m_text_top(px, value.fblock_ptr, value.data_ptr);
|
||||
|
||||
value.data_ptr->nontext_render(graph, rs.pos.x, y);
|
||||
_m_inser_if_traceable(rs.pos.x, y, sz, value.fblock_ptr);
|
||||
rs.pos.x += static_cast<int>(sz.width);
|
||||
|
||||
if(lastpos < y)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
if (value.data_ptr->is_text())
|
||||
{
|
||||
//hold the block while the text is empty,
|
||||
//it stands for the first block
|
||||
if(text.empty())
|
||||
if (text.empty())
|
||||
block_start = render_iterator;
|
||||
|
||||
text += value.data_ptr->text();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(text.size())
|
||||
{
|
||||
_m_draw_block(graph, text, block_start, rs);
|
||||
if(lastpos <= rs.pos.y)
|
||||
return false;
|
||||
text.clear();
|
||||
}
|
||||
nana::size sz = value.data_ptr->size();
|
||||
|
||||
pixel_tag px = rs.pixels[rs.index];
|
||||
if ((rs.allowed_width < rs.pos.x + sz.width) && (rs.pos.x != px.x_base))
|
||||
{
|
||||
//Change a line.
|
||||
rs.pos.y += static_cast<int>(px.pixels);
|
||||
px = rs.pixels[++rs.index];
|
||||
rs.pos.x = px.x_base;
|
||||
}
|
||||
|
||||
int y = rs.pos.y + _m_text_top(px, value.fblock_ptr, value.data_ptr);
|
||||
|
||||
value.data_ptr->nontext_render(graph, rs.pos.x, y);
|
||||
_m_insert_if_traceable(rs.pos.x, y, sz, value.fblock_ptr);
|
||||
rs.pos.x += static_cast<int>(sz.width);
|
||||
|
||||
if(lastpos < y)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(text.size())
|
||||
@ -575,7 +571,7 @@ namespace nana
|
||||
}
|
||||
|
||||
|
||||
_m_inser_if_traceable(rs.pos.x, y, sz, fblock_ptr);
|
||||
_m_insert_if_traceable(rs.pos.x, y, sz, fblock_ptr);
|
||||
rs.pos.x += static_cast<int>(sz.width);
|
||||
|
||||
if(text_range.second < len)
|
||||
@ -604,13 +600,13 @@ namespace nana
|
||||
dstream dstream_;
|
||||
bool format_enabled_ = false;
|
||||
::nana::widgets::skeletons::fblock * fblock_ = nullptr;
|
||||
std::deque<traceable> traceable_;
|
||||
::std::deque<traceable> traceable_;
|
||||
|
||||
::nana::paint::font font_;
|
||||
struct def_font_tag
|
||||
{
|
||||
::std::string font_name;
|
||||
std::size_t font_size;
|
||||
double font_size;
|
||||
bool font_bold;
|
||||
::nana::color fgcolor;
|
||||
}def_;
|
||||
|
@ -1953,7 +1953,6 @@ namespace nana
|
||||
index_pairs already_selected;
|
||||
index_pairs selections;
|
||||
|
||||
//nana::timer timer;
|
||||
bool scroll_direction;
|
||||
unsigned scroll_step{ 1 };
|
||||
unsigned mouse_move_timestamp{ 0 };
|
||||
@ -4134,6 +4133,7 @@ namespace nana
|
||||
}
|
||||
else if (ptr_where.first == parts::list_blank) //not selected
|
||||
{
|
||||
//Start box selection if mulit-selection is enabled
|
||||
if (arg.is_left_button() && (!lister.single_status(true)))
|
||||
essence_->start_mouse_selection(arg.pos);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
* @contributors: dareg
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../../detail/platform_spec_selector.hpp"
|
||||
#include <nana/paint/detail/native_paint_interface.hpp>
|
||||
#include <nana/paint/pixel_buffer.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
@ -145,14 +145,14 @@ namespace detail
|
||||
#if defined(NANA_USE_XFT)
|
||||
std::string utf8str = to_utf8(std::wstring(text, len));
|
||||
XGlyphInfo ext;
|
||||
XftFont * fs = reinterpret_cast<XftFont*>(dw->font->handle);
|
||||
XftFont * fs = reinterpret_cast<XftFont*>(dw->font->native_handle());
|
||||
::XftTextExtentsUtf8(nana::detail::platform_spec::instance().open_display(), fs,
|
||||
reinterpret_cast<XftChar8*>(const_cast<char*>(utf8str.c_str())), utf8str.size(), &ext);
|
||||
return nana::size(ext.xOff, fs->ascent + fs->descent);
|
||||
#else
|
||||
XRectangle ink;
|
||||
XRectangle logic;
|
||||
::XmbTextExtents(reinterpret_cast<XFontSet>(dw->font->handle), text, len, &ink, &logic);
|
||||
::XmbTextExtents(reinterpret_cast<XFontSet>(dw->font->native_handle()), text, len, &ink, &logic);
|
||||
return nana::size(logic.width, logic.height);
|
||||
#endif
|
||||
#endif
|
||||
@ -185,7 +185,7 @@ namespace detail
|
||||
#elif defined(NANA_X11)
|
||||
auto disp = ::nana::detail::platform_spec::instance().open_display();
|
||||
#if defined(NANA_USE_XFT)
|
||||
auto fs = reinterpret_cast<XftFont*>(dw->font->handle);
|
||||
auto fs = reinterpret_cast<XftFont*>(dw->font->native_handle());
|
||||
|
||||
//Fixed missing array declaration by dareg
|
||||
std::unique_ptr<FT_UInt[]> glyphs_ptr(new FT_UInt[len]);
|
||||
@ -197,7 +197,7 @@ namespace detail
|
||||
}
|
||||
XftDrawGlyphs(dw->xftdraw, &(dw->xft_fgcolor), fs, pos.x, pos.y + fs->ascent, glyphs_ptr.get(), len);
|
||||
#else
|
||||
XFontSet fs = reinterpret_cast<XFontSet>(dw->font->handle);
|
||||
XFontSet fs = reinterpret_cast<XFontSet>(dw->font->native_handle());
|
||||
XFontSetExtents * ext = ::XExtentsOfFontSet(fs);
|
||||
XFontStruct ** fontstructs;
|
||||
char ** font_names;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Paint Graphics Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -10,7 +10,7 @@
|
||||
* @file: nana/paint/graphics.cpp
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
#include <nana/gui/detail/bedrock.hpp>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/paint/detail/native_paint_interface.hpp>
|
||||
@ -24,8 +24,19 @@
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
#include "../detail/platform_abstraction.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
font_style::font_style(unsigned weight, bool italic, bool underline, bool strike_out) :
|
||||
weight(weight),
|
||||
italic(italic),
|
||||
underline(underline),
|
||||
strike_out(strike_out)
|
||||
{}
|
||||
}
|
||||
namespace paint
|
||||
{
|
||||
namespace detail
|
||||
@ -56,33 +67,39 @@ namespace paint
|
||||
//class font
|
||||
struct font::impl_type
|
||||
{
|
||||
typedef nana::detail::platform_spec::font_ptr_t ptr_t;
|
||||
ptr_t font_ptr;
|
||||
std::shared_ptr<font_interface> real_font;
|
||||
};
|
||||
|
||||
font::font()
|
||||
: impl_(new impl_type)
|
||||
{
|
||||
impl_->font_ptr = nana::detail::platform_spec::instance().default_native_font();
|
||||
impl_->real_font = platform_abstraction::default_font(nullptr);
|
||||
}
|
||||
|
||||
font::font(drawable_type dw)
|
||||
: impl_(new impl_type)
|
||||
{
|
||||
impl_->font_ptr = dw->font;
|
||||
impl_->real_font = dw->font;
|
||||
}
|
||||
|
||||
font::font(const font& rhs)
|
||||
: impl_(new impl_type)
|
||||
{
|
||||
if(rhs.impl_)
|
||||
impl_->font_ptr = rhs.impl_->font_ptr;
|
||||
impl_->real_font = rhs.impl_->real_font;
|
||||
}
|
||||
|
||||
font::font(const std::string& name, unsigned size, bool bold, bool italic, bool underline, bool strike_out)
|
||||
: impl_(new impl_type)
|
||||
font::font(const std::string& font_family, double size_pt, const font_style& fs):
|
||||
impl_(new impl_type)
|
||||
{
|
||||
make(name, size, bold, italic, underline, strike_out);
|
||||
impl_->real_font = platform_abstraction::make_font(font_family, size_pt, fs);
|
||||
}
|
||||
|
||||
|
||||
font::font(double size_pt, const path_type& truetype, const font_style& fs) :
|
||||
impl_(new impl_type)
|
||||
{
|
||||
impl_->real_font = platform_abstraction::make_font_from_ttf(truetype, size_pt, fs);
|
||||
}
|
||||
|
||||
font::~font()
|
||||
@ -92,23 +109,7 @@ namespace paint
|
||||
|
||||
bool font::empty() const
|
||||
{
|
||||
return ((nullptr == impl_) || (nullptr == impl_->font_ptr));
|
||||
}
|
||||
|
||||
void font::make(const std::string& name, unsigned size, bool bold, bool italic, bool underline, bool strike_out)
|
||||
{
|
||||
size = nana::detail::platform_spec::instance().font_size_to_height(size);
|
||||
make_raw(name, size, bold ? 700 : 400, italic, underline, strike_out);
|
||||
}
|
||||
|
||||
void font::make_raw(const std::string& name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out)
|
||||
{
|
||||
if(impl_)
|
||||
{
|
||||
auto t = nana::detail::platform_spec::instance().make_native_font(name.c_str(), height, weight, italic, underline, strike_out);
|
||||
if(t)
|
||||
impl_->font_ptr = t;
|
||||
}
|
||||
return ((nullptr == impl_) || (nullptr == impl_->real_font));
|
||||
}
|
||||
|
||||
void font::set_default() const
|
||||
@ -116,74 +117,69 @@ namespace paint
|
||||
if(empty())
|
||||
return;
|
||||
|
||||
nana::detail::platform_spec::instance().default_native_font(impl_->font_ptr);
|
||||
platform_abstraction::default_font(impl_->real_font);
|
||||
}
|
||||
|
||||
std::string font::name() const
|
||||
{
|
||||
if(empty()) return std::string();
|
||||
|
||||
return to_utf8(impl_->font_ptr->name);
|
||||
return impl_->real_font->family();
|
||||
}
|
||||
|
||||
unsigned font::size() const
|
||||
double font::size() const
|
||||
{
|
||||
if(empty()) return 0;
|
||||
return nana::detail::platform_spec::instance().font_height_to_size(impl_->font_ptr->height);
|
||||
|
||||
return impl_->real_font->size();
|
||||
}
|
||||
|
||||
bool font::bold() const
|
||||
{
|
||||
if(empty()) return false;
|
||||
return (impl_->font_ptr->weight >= 700);
|
||||
}
|
||||
|
||||
unsigned font::height() const
|
||||
{
|
||||
if(empty()) return 0;
|
||||
return (impl_->font_ptr->height);
|
||||
return (impl_->real_font->style().weight >= 700);
|
||||
}
|
||||
|
||||
unsigned font::weight() const
|
||||
{
|
||||
if(empty()) return 0;
|
||||
return (impl_->font_ptr->weight);
|
||||
return impl_->real_font->style().weight;
|
||||
}
|
||||
|
||||
bool font::italic() const
|
||||
{
|
||||
if(empty()) return false;
|
||||
return (impl_->font_ptr->italic);
|
||||
return impl_->real_font->style().italic;
|
||||
}
|
||||
|
||||
bool font::underline() const
|
||||
{
|
||||
if(empty()) return false;
|
||||
return (impl_->font_ptr->underline);
|
||||
return impl_->real_font->style().underline;
|
||||
}
|
||||
|
||||
bool font::strikeout() const
|
||||
{
|
||||
if(empty()) return false;
|
||||
return (impl_->font_ptr->strikeout);
|
||||
return impl_->real_font->style().strike_out;
|
||||
}
|
||||
|
||||
native_font_type font::handle() const
|
||||
{
|
||||
if(empty()) return nullptr;
|
||||
return reinterpret_cast<native_font_type>(impl_->font_ptr->handle);
|
||||
return impl_->real_font->native_handle();
|
||||
}
|
||||
|
||||
void font::release()
|
||||
{
|
||||
if(impl_)
|
||||
impl_->font_ptr.reset();
|
||||
impl_->real_font.reset();
|
||||
}
|
||||
|
||||
font & font::operator=(const font& rhs)
|
||||
{
|
||||
if(impl_ && rhs.impl_ && (this != &rhs))
|
||||
impl_->font_ptr = rhs.impl_->font_ptr;
|
||||
impl_->real_font = rhs.impl_->real_font;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -191,7 +187,7 @@ namespace paint
|
||||
bool font::operator==(const font& rhs) const
|
||||
{
|
||||
if(empty() == rhs.empty())
|
||||
return (empty() || (impl_->font_ptr->handle == rhs.impl_->font_ptr->handle));
|
||||
return (empty() || (impl_->real_font == rhs.impl_->real_font));
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -199,7 +195,7 @@ namespace paint
|
||||
bool font::operator!=(const font& rhs) const
|
||||
{
|
||||
if(empty() == rhs.empty())
|
||||
return ((empty() == false) && (impl_->font_ptr->handle != rhs.impl_->font_ptr->handle));
|
||||
return ((empty() == false) && (impl_->real_font != rhs.impl_->real_font));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -305,7 +301,7 @@ namespace paint
|
||||
dw->string.tab_length = reuse->string.tab_length;
|
||||
}
|
||||
else
|
||||
dw->font = impl_->font_shadow.impl_->font_ptr;
|
||||
dw->font = impl_->font_shadow.impl_->real_font;
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
HDC hdc = ::GetDC(0);
|
||||
@ -325,7 +321,7 @@ namespace paint
|
||||
if(bmp)
|
||||
{
|
||||
::DeleteObject((HBITMAP)::SelectObject(cdc, bmp));
|
||||
::DeleteObject(::SelectObject(cdc, dw->font->handle));
|
||||
::DeleteObject(::SelectObject(cdc, dw->font->native_handle()));
|
||||
|
||||
dw->context = cdc;
|
||||
dw->pixmap = bmp;
|
||||
@ -388,9 +384,9 @@ namespace paint
|
||||
impl_->font_shadow = f;
|
||||
if(impl_->handle && (false == f.empty()))
|
||||
{
|
||||
impl_->handle->font = f.impl_->font_ptr;
|
||||
impl_->handle->font = f.impl_->real_font;
|
||||
#if defined(NANA_WINDOWS)
|
||||
::SelectObject(impl_->handle->context, reinterpret_cast<HFONT>(f.impl_->font_ptr->handle));
|
||||
::SelectObject(impl_->handle->context, reinterpret_cast<HFONT>(f.impl_->real_font->native_handle()));
|
||||
#endif
|
||||
impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;
|
||||
impl_->handle->string.whitespace_pixels = detail::raw_text_extent_size(impl_->handle, L" ", 1).width;
|
||||
@ -489,8 +485,8 @@ namespace paint
|
||||
delete [] dx;
|
||||
#elif defined(NANA_X11) && defined(NANA_USE_XFT)
|
||||
|
||||
Display * disp = nana::detail::platform_spec::instance().open_display();
|
||||
XftFont * xft = impl_->handle->font->handle;
|
||||
auto disp = nana::detail::platform_spec::instance().open_display();
|
||||
auto xft = reinterpret_cast<XftFont*>(impl_->handle->font->native_handle());
|
||||
|
||||
XGlyphInfo extents;
|
||||
for(std::size_t i = 0; i < len; ++i)
|
||||
@ -547,12 +543,12 @@ namespace paint
|
||||
if(impl_->handle->font)
|
||||
{
|
||||
#if defined(NANA_USE_XFT)
|
||||
XftFont * fs = reinterpret_cast<XftFont*>(impl_->handle->font->handle);
|
||||
auto fs = reinterpret_cast<XftFont*>(impl_->handle->font->native_handle());
|
||||
ascent = fs->ascent;
|
||||
descent = fs->descent;
|
||||
internal_leading = 0;
|
||||
#else
|
||||
XFontSet fs = reinterpret_cast<XFontSet>(impl_->handle->font->handle);
|
||||
auto fs = reinterpret_cast<XFontSet>(impl_->handle->font->native_handle());
|
||||
XFontSetExtents * ext = ::XExtentsOfFontSet(fs);
|
||||
XFontStruct ** fontstructs;
|
||||
char ** font_names;
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <nana/push_ignore_diagnostic>
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
#include <nana/paint/image.hpp>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
@ -11,7 +11,7 @@
|
||||
* @note: The format of Xorg 16bits depth is 565
|
||||
*/
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
#include <nana/paint/pixel_buffer.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/paint/detail/native_paint_interface.hpp>
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
#include <nana/paint/text_renderer.hpp>
|
||||
#include <nana/unicode_bidi.hpp>
|
||||
#include <nana/paint/detail/native_paint_interface.hpp>
|
||||
|
161
source/paint/truetype.hpp
Normal file
161
source/paint/truetype.hpp
Normal file
@ -0,0 +1,161 @@
|
||||
#ifndef TTF_HEADER_INCLUDED
|
||||
#define TTF_HEADER_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <nana/charset.hpp>
|
||||
#include <nana/filesystem/filesystem.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace spec
|
||||
{
|
||||
class truetype
|
||||
{
|
||||
struct tt_offset_table
|
||||
{
|
||||
std::uint16_t major_version;
|
||||
std::uint16_t minor_version;
|
||||
std::uint16_t num_of_tables;
|
||||
std::uint16_t search_range;
|
||||
std::uint16_t entry_selector;
|
||||
std::uint16_t range_shift;
|
||||
};
|
||||
|
||||
struct tt_table_directory
|
||||
{
|
||||
char name[4]; //table name
|
||||
std::uint32_t checksum; //Check sum
|
||||
std::uint32_t offset; //Offset from beginning of file
|
||||
std::uint32_t length; //length of the table in bytes
|
||||
};
|
||||
|
||||
struct tt_name_table_header
|
||||
{
|
||||
std::uint16_t format_selector; //format selector. Always 0
|
||||
std::uint16_t name_records_count; //Name Records count
|
||||
std::uint16_t storage_offset; //Offset for strings storage, from start of the table
|
||||
};
|
||||
|
||||
struct tt_name_record
|
||||
{
|
||||
std::uint16_t platform_id;
|
||||
std::uint16_t encoding_id;
|
||||
std::uint16_t language_id;
|
||||
std::uint16_t name_id;
|
||||
std::uint16_t string_length;
|
||||
std::uint16_t string_offset; //from start of storage area
|
||||
};
|
||||
public:
|
||||
using path_type = ::std::experimental::filesystem::path;
|
||||
|
||||
truetype(const path_type& filename)
|
||||
{
|
||||
std::ifstream ifs{ filename, std::ios::binary };
|
||||
if (!ifs.is_open())
|
||||
return;
|
||||
|
||||
tt_offset_table offset_table;
|
||||
if (ifs.read(reinterpret_cast<char*>(&offset_table), sizeof offset_table).gcount() != sizeof offset_table)
|
||||
return;
|
||||
|
||||
const std::size_t num_of_tables = _m_swap(offset_table.num_of_tables);
|
||||
for (std::size_t i = 0; i < num_of_tables; ++i)
|
||||
{
|
||||
tt_table_directory table_directory;
|
||||
if (ifs.read(reinterpret_cast<char*>(&table_directory), sizeof table_directory).gcount() != sizeof table_directory)
|
||||
return;
|
||||
|
||||
if (reinterpret_cast<const std::uint32_t&>("name") == reinterpret_cast<std::uint32_t&>(table_directory.name))
|
||||
{
|
||||
//const std::size_t length = _m_swap(table_directory.length);
|
||||
const std::size_t directory_offset = _m_swap(table_directory.offset);
|
||||
|
||||
ifs.seekg(directory_offset, std::ios::beg);
|
||||
|
||||
tt_name_table_header name_table;
|
||||
if (ifs.read(reinterpret_cast<char*>(&name_table), sizeof name_table).gcount() != sizeof name_table)
|
||||
return;
|
||||
|
||||
const std::size_t name_records_count = _m_swap(name_table.name_records_count);
|
||||
const std::size_t storage_offset = _m_swap(name_table.storage_offset);
|
||||
|
||||
for (std::size_t u = 0; u < name_records_count; ++u)
|
||||
{
|
||||
tt_name_record record;
|
||||
if (ifs.read(reinterpret_cast<char*>(&record), sizeof record).gcount() != sizeof record)
|
||||
return;
|
||||
|
||||
if ((0 == record.string_length) || (0x100 != record.name_id))
|
||||
continue;
|
||||
|
||||
std::size_t string_length = _m_swap(record.string_length);
|
||||
|
||||
auto const filepos = ifs.tellg();
|
||||
ifs.seekg(directory_offset + _m_swap(record.string_offset) + storage_offset, std::ios::beg);
|
||||
|
||||
std::string text;
|
||||
|
||||
//Check if it is unicode
|
||||
if ((0 == record.platform_id) || (record.platform_id == 0x300 && record.encoding_id == 0x100))
|
||||
{
|
||||
if (0 == (string_length & 1)) //the string_length must be
|
||||
{
|
||||
//This is unicode
|
||||
text.resize(string_length);
|
||||
ifs.read(&text.front(), string_length);
|
||||
|
||||
for (auto i = 0; i < string_length; i += 2)
|
||||
{
|
||||
std::swap(text[i], text[i + 1]);
|
||||
}
|
||||
text = nana::charset(text, nana::unicode::utf16).to_bytes(nana::unicode::utf8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text.resize(string_length);
|
||||
ifs.read(&text.front(), string_length);
|
||||
}
|
||||
|
||||
if (!text.empty())
|
||||
{
|
||||
switch (record.name_id)
|
||||
{
|
||||
case 0x100:
|
||||
font_family_.swap(text);
|
||||
break;
|
||||
case 0x400:
|
||||
text.clear();
|
||||
}
|
||||
}
|
||||
ifs.seekg(filepos, std::ios::beg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string& font_family() const
|
||||
{
|
||||
return font_family_;
|
||||
}
|
||||
private:
|
||||
static std::uint16_t _m_swap(std::uint16_t val)
|
||||
{
|
||||
return (val << 8) | (val >> 8);
|
||||
}
|
||||
|
||||
static std::uint32_t _m_swap(std::uint32_t val)
|
||||
{
|
||||
return (static_cast<std::uint32_t>(_m_swap(std::uint16_t(val & 0xFFFF))) << 16) | _m_swap(std::uint16_t(val >> 16));
|
||||
}
|
||||
private:
|
||||
std::string font_family_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -19,11 +19,11 @@
|
||||
#include <cstring>
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
# include <windows.h>
|
||||
#elif defined(NANA_X11)
|
||||
#include <nana/detail/platform_spec_selector.hpp>
|
||||
#include <nana/gui/detail/bedrock.hpp>
|
||||
#include <nana/gui/detail/basic_window.hpp>
|
||||
# include "../detail/platform_spec_selector.hpp"
|
||||
# include <nana/gui/detail/bedrock.hpp>
|
||||
# include <nana/gui/detail/basic_window.hpp>
|
||||
#endif
|
||||
|
||||
namespace nana{ namespace system{
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <nana/detail/win32/platform_spec.hpp>
|
||||
#include "../detail/mswin/platform_spec.hpp"
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user