30#include <wx/filename.h>
49 return (mi1->icon_name.CmpNoCase(mi2->icon_name));
55 msg.Printf(
"DPMM: %g ScaleFactorExp: %g", displayDPmm,
56 g_MarkScaleFactorExp);
60 wxChar sep = wxFileName::GetPathSeparator();
61 if (UserIconPath.Last() != sep) UserIconPath.Append(sep);
62 UserIconPath.Append(
"UserIcons/");
64 wxLogMessage(
"Looking for UserIcons at " + UserIconPath);
66 if (wxDir::Exists(UserIconPath)) {
67 wxLogMessage(
"Loading UserIcons from " + UserIconPath);
68 wxArrayString FileList;
70 wxBitmap default_bm = wxBitmap(1, 1);
72 int n_files = wxDir::GetAllFiles(UserIconPath, &FileList,
"", wxDIR_FILES);
74 for (
int ifile = 0; ifile < n_files; ifile++) {
76 g_bUserIconsFirst ? FileList[n_files - ifile - 1] : FileList[ifile];
79 wxString iconname = fn.GetName();
81 if (fn.GetExt().Lower() ==
"xpm") {
82 if (icon1.LoadFile(name, wxBITMAP_TYPE_XPM)) {
83 wxLogMessage(
"Adding icon: " + iconname);
84 wxImage image = icon1.ConvertToImage();
85 ProcessIcon(image, iconname, iconname, g_bUserIconsFirst);
88 if (fn.GetExt().Lower() ==
"png") {
89 if (icon1.LoadFile(name, wxBITMAP_TYPE_PNG)) {
90 wxLogMessage(
"Adding icon: " + iconname);
91 wxImage image = icon1.ConvertToImage();
92 ProcessIcon(image, iconname, iconname, g_bUserIconsFirst);
95 if (fn.GetExt().Lower() ==
"svg") {
99 double IconScaleFactor = 1.0;
101 wxImage image =
LoadSVG(name, w, h, &default_bm).ConvertToImage();
104 wxRect rClip = CropImageOnAlpha(image);
105 int Clip_max = wxMax(rClip.GetWidth(), rClip.GetHeight());
106 if (Clip_max > (displayDPmm * 20))
107 IconScaleFactor = Clip_max / displayDPmm * 20;
108 int Clip_min = wxMin(rClip.GetWidth(), rClip.GetHeight());
109 if (Clip_min < (displayDPmm * 3))
110 IconScaleFactor = Clip_min / displayDPmm * 3;
112 IconScaleFactor *= g_MarkScaleFactorExp;
116 LoadSVG(name, (
int)(w * IconScaleFactor),
117 (
int)(h * IconScaleFactor), &default_bm,
false)
119 pmi = ProcessIcon(iconSVG, iconname, iconname, g_bUserIconsFirst);
121 if (pmi) pmi->preScaled =
true;
127MarkIcon *WayPointmanGui::ProcessIcon(wxImage image,
const wxString &key,
128 const wxString &description,
135 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
136 pmi = (
MarkIcon *)m_waypoint_man.m_pIconArray->Item(i);
137 if (pmi->icon_name.IsSameAs(key)) {
139 delete pmi->piconBitmap;
146 pmi->icon_name = key;
148 m_waypoint_man.m_pIconArray->Insert(pmi, 0);
150 m_waypoint_man.m_pIconArray->Add(pmi);
154 wxBitmap *pbm =
new wxBitmap(image);
155 pmi->icon_name = key;
156 pmi->icon_description = description;
157 pmi->piconBitmap = NULL;
158 pmi->icon_texture = 0;
159 pmi->preScaled =
false;
160 pmi->iconImage = pbm->ConvertToImage();
161 pmi->m_blistImageOK =
false;
167void WayPointmanGui::ProcessIcons(
ocpnStyle::Style *style,
double displayDPmm) {
168 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
170 delete pmi->piconBitmap;
173 m_waypoint_man.m_pIconArray->Clear();
175 ProcessDefaultIcons(displayDPmm);
181 ProcessUserIcons(style, displayDPmm);
183 if (NULL != m_waypoint_man.pmarkicon_image_list) {
184 m_waypoint_man.pmarkicon_image_list->RemoveAll();
185 delete m_waypoint_man.pmarkicon_image_list;
186 m_waypoint_man.pmarkicon_image_list = NULL;
194 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
196 w = wxMax(w, pmi->iconImage.GetWidth());
197 h = wxMax(h, pmi->iconImage.GetHeight());
200 m_waypoint_man.m_bitmapSizeForList = wxMax(w, h);
201 m_waypoint_man.m_bitmapSizeForList =
202 wxMin(100, m_waypoint_man.m_bitmapSizeForList);
205void WayPointmanGui::ProcessDefaultIcons(
double displayDPmm) {
207 appendOSDirSlash(&iconDir);
208 iconDir.append(
"uidata");
209 appendOSDirSlash(&iconDir);
210 iconDir.append(
"markicons");
211 appendOSDirSlash(&iconDir);
216 if (m_waypoint_man.m_pLegacyIconArray)
217 m_waypoint_man.m_pLegacyIconArray->Clear();
219 m_waypoint_man.m_pLegacyIconArray =
220 new SortedArrayOfMarkIcon(CompareMarkIcons);
222 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Empty.svg",
"empty",
"Empty",
224 if (pmi) pmi->preScaled =
true;
225 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Triangle.svg",
"triangle",
226 "Triangle", displayDPmm);
227 if (pmi) pmi->preScaled =
true;
228 pmi = ProcessLegacyIcon(iconDir +
"1st-Active-Waypoint.svg",
"activepoint",
229 "Active WP", displayDPmm);
230 if (pmi) pmi->preScaled =
true;
231 pmi = ProcessLegacyIcon(iconDir +
"Marks-Boarding-Location.svg",
"boarding",
232 "Boarding Location", displayDPmm);
233 if (pmi) pmi->preScaled =
true;
234 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Airplane.svg",
"airplane",
235 "Airplane", displayDPmm);
236 if (pmi) pmi->preScaled =
true;
237 pmi = ProcessLegacyIcon(iconDir +
"1st-Anchorage.svg",
"anchorage",
238 "Anchorage", displayDPmm);
239 if (pmi) pmi->preScaled =
true;
240 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Anchor2.svg",
"anchor",
"Anchor",
242 if (pmi) pmi->preScaled =
true;
243 pmi = ProcessLegacyIcon(iconDir +
"Marks-Boundary.svg",
"boundary",
244 "Boundary Mark", displayDPmm);
245 if (pmi) pmi->preScaled =
true;
246 pmi = ProcessLegacyIcon(iconDir +
"Marks-Buoy-TypeA.svg",
"buoy1",
247 "buoy Type A", displayDPmm);
248 if (pmi) pmi->preScaled =
true;
249 pmi = ProcessLegacyIcon(iconDir +
"Marks-Buoy-TypeB.svg",
"buoy2",
250 "buoy Type B", displayDPmm);
251 if (pmi) pmi->preScaled =
true;
252 pmi = ProcessLegacyIcon(iconDir +
"Activity-Campfire.svg",
"campfire",
253 "Campfire", displayDPmm);
254 if (pmi) pmi->preScaled =
true;
255 pmi = ProcessLegacyIcon(iconDir +
"Activity-Camping.svg",
"camping",
256 "Camping Spot", displayDPmm);
257 if (pmi) pmi->preScaled =
true;
258 pmi = ProcessLegacyIcon(iconDir +
"Sea-Floor-Coral.svg",
"coral",
"Coral",
260 if (pmi) pmi->preScaled =
true;
261 pmi = ProcessLegacyIcon(iconDir +
"Activity-Fishing.svg",
"fishhaven",
262 "Fish Haven", displayDPmm);
263 if (pmi) pmi->preScaled =
true;
264 pmi = ProcessLegacyIcon(iconDir +
"Activity-Fishing.svg",
"fishing",
265 "Fishing Spot", displayDPmm);
266 if (pmi) pmi->preScaled =
true;
267 pmi = ProcessLegacyIcon(iconDir +
"Activity-Fishing.svg",
"fish",
"Fish",
269 if (pmi) pmi->preScaled =
true;
270 pmi = ProcessLegacyIcon(iconDir +
"Marks-Mooring-Buoy.svg",
"float",
"Float",
272 if (pmi) pmi->preScaled =
true;
273 pmi = ProcessLegacyIcon(iconDir +
"Service-Food.svg",
"food",
"Food",
275 if (pmi) pmi->preScaled =
true;
276 pmi = ProcessLegacyIcon(iconDir +
"Service-Fuel-Pump-Diesel-Petrol.svg",
277 "fuel",
"Fuel", displayDPmm);
278 if (pmi) pmi->preScaled =
true;
279 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Green.svg",
"greenlite",
280 "Green Light", displayDPmm);
281 if (pmi) pmi->preScaled =
true;
282 pmi = ProcessLegacyIcon(iconDir +
"Sea-Floor-Sea-Weed.svg",
"kelp",
"Kelp",
284 if (pmi) pmi->preScaled =
true;
285 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-TypeA.svg",
"light",
286 "Light Type A", displayDPmm);
287 if (pmi) pmi->preScaled =
true;
288 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-TypeB.svg",
"light1",
289 "Light Type B", displayDPmm);
290 if (pmi) pmi->preScaled =
true;
291 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Vessel.svg",
"litevessel",
292 "litevessel", displayDPmm);
293 if (pmi) pmi->preScaled =
true;
294 pmi = ProcessLegacyIcon(iconDir +
"1st-Man-Overboard.svg",
"mob",
"MOB",
296 if (pmi) pmi->preScaled =
true;
297 pmi = ProcessLegacyIcon(iconDir +
"Marks-Mooring-Buoy.svg",
"mooring",
298 "Mooring buoy", displayDPmm);
299 if (pmi) pmi->preScaled =
true;
300 pmi = ProcessLegacyIcon(iconDir +
"Marks-Mooring-Buoy-Super.svg",
"oilbuoy",
301 "Oil buoy", displayDPmm);
302 if (pmi) pmi->preScaled =
true;
303 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Oil-Platform.svg",
"platform",
304 "Platform", displayDPmm);
305 if (pmi) pmi->preScaled =
true;
306 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Red-Green.svg",
"redgreenlite",
307 "Red/Green Light", displayDPmm);
308 if (pmi) pmi->preScaled =
true;
309 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Red.svg",
"redlite",
310 "Red Light", displayDPmm);
311 if (pmi) pmi->preScaled =
true;
312 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Rock-Exposed.svg",
"rock1",
313 "Rock (exposed)", displayDPmm);
314 if (pmi) pmi->preScaled =
true;
315 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Rock-Awash.svg",
"rock2",
316 "Rock, (awash)", displayDPmm);
317 if (pmi) pmi->preScaled =
true;
318 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Sandbar.svg",
"sand",
"Sand",
320 if (pmi) pmi->preScaled =
true;
321 pmi = ProcessLegacyIcon(iconDir +
"Activity-Diving-Scuba-Flag.svg",
"scuba",
322 "Scuba", displayDPmm);
323 if (pmi) pmi->preScaled =
true;
324 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Sandbar.svg",
"shoal",
"Shoal",
326 if (pmi) pmi->preScaled =
true;
327 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Snag.svg",
"snag",
"Snag",
329 if (pmi) pmi->preScaled =
true;
330 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Square.svg",
"square",
"Square",
332 if (pmi) pmi->preScaled =
true;
333 pmi = ProcessLegacyIcon(iconDir +
"1st-Diamond.svg",
"diamond",
"Diamond",
335 if (pmi) pmi->preScaled =
true;
336 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Circle.svg",
"circle",
"Circle",
338 if (pmi) pmi->preScaled =
true;
339 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Wreck1.svg",
"wreck1",
"Wreck A",
341 if (pmi) pmi->preScaled =
true;
342 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Wreck2.svg",
"wreck2",
"Wreck B",
344 if (pmi) pmi->preScaled =
true;
345 pmi = ProcessLegacyIcon(iconDir +
"Symbol-X-Small-Blue.svg",
"xmblue",
346 "Blue X", displayDPmm);
347 if (pmi) pmi->preScaled =
true;
348 pmi = ProcessLegacyIcon(iconDir +
"Symbol-X-Small-Green.svg",
"xmgreen",
349 "Green X", displayDPmm);
350 if (pmi) pmi->preScaled =
true;
351 pmi = ProcessLegacyIcon(iconDir +
"Symbol-X-Small-Red.svg",
"xmred",
"Red X",
353 if (pmi) pmi->preScaled =
true;
356 if (m_waypoint_man.m_pExtendedIconArray) {
357 m_waypoint_man.m_pExtendedIconArray->Clear();
359 m_waypoint_man.m_pExtendedIconArray =
360 new SortedArrayOfMarkIcon(CompareMarkIcons);
364 wxArrayString FileList;
367 int n_files = wxDir::GetAllFiles( iconDir, &FileList );
373 for(
int ifile = 0; ifile < n_files; ifile++ ) {
374 wxString name = FileList[ifile];
376 wxFileName fn( name );
378 if( fn.GetExt().Lower() ==
"svg" ) {
379 wxBitmap bmt =
LoadSVG(name, -1, -1 );
386 for(
int ifile = 0; ifile < n_files; ifile++ ) {
387 wxString name = FileList[ifile];
389 wxFileName fn( name );
390 wxString iconname = fn.GetName();
392 if( fn.GetExt().Lower() ==
"svg" ) {
393 wxImage iconSVG =
LoadSVG( name, (
int)bm_size, (
int)bm_size );
394 MarkIcon * pmi = ProcessExtendedIcon( iconSVG, iconname, iconname );
396 pmi->preScaled =
true;
401 wxArrayString FileList;
403 double bm_size = wxMax(4.0, floor(displayDPmm * 12.0));
405 bm_size *= g_MarkScaleFactorExp;
407 int n_files = wxDir::GetAllFiles(iconDir, &FileList);
411 for (
int ifile = 0; ifile < n_files; ifile++) {
412 wxString name = FileList[ifile];
415 wxString iconname = fn.GetName();
418 if (fn.GetExt().Lower() ==
"svg") {
424 w = wxMax(wxMax(w, h), 15);
425 bm_size = w * g_MarkScaleFactorExp;
434 float nominal_legacy_icon_size_pixels =
435 wxMax(4.0, floor(displayDPmm * 12.0));
437 float pix_factor = nominal_legacy_icon_size_pixels / 68.0;
438 bm_size *= pix_factor;
441 wxBitmap bmp =
LoadSVG(name, (
int)bm_size, (
int)bm_size);
443 wxImage iconSVG = bmp.ConvertToImage();
445 MarkIcon *pmi = ProcessExtendedIcon(iconSVG, iconname, iconname);
446 if (pmi) pmi->preScaled =
true;
448 wxLogMessage(
"Failed loading mark icon " + name);
457 auto size = m_waypoint_man.m_pLegacyIconArray->GetCount();
458 for (
unsigned int i = 0; i < size; i++) {
459 pmi = (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(i);
460 m_waypoint_man.m_pIconArray->Add(pmi);
463 size = m_waypoint_man.m_pExtendedIconArray->GetCount();
464 for (
unsigned int i = 0; i < size; i++) {
465 pmi = (
MarkIcon *)m_waypoint_man.m_pExtendedIconArray->Item(i);
470 auto legacy_count = m_waypoint_man.m_pLegacyIconArray->GetCount();
471 for (
unsigned int j = 0; j < legacy_count; j++) {
473 (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(j);
474 if (pmiLegacy->icon_name.IsSameAs(pmi->icon_name)) {
479 if (!noAdd) m_waypoint_man.m_pIconArray->Add(pmi);
483void WayPointmanGui::ReloadAllIcons(
double displayDPmm) {
484 ProcessIcons(g_StyleManager->GetCurrentStyle(), displayDPmm);
486 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
489 if (m_waypoint_man.m_cs == GLOBAL_COLOR_SCHEME_DUSK) {
490 dim_image = m_waypoint_man.CreateDimImage(pmi->iconImage, .50);
491 pmi->iconImage = dim_image;
492 }
else if (m_waypoint_man.m_cs == GLOBAL_COLOR_SCHEME_NIGHT) {
493 dim_image = m_waypoint_man.CreateDimImage(pmi->iconImage, .20);
494 pmi->iconImage = dim_image;
497 ReloadRoutepointIcons();
500void WayPointmanGui::SetColorScheme(ColorScheme cs,
double displayDPmm) {
501 m_waypoint_man.m_cs = cs;
502 ReloadAllIcons(displayDPmm);
505MarkIcon *WayPointmanGui::ProcessLegacyIcon(wxString fileName,
507 const wxString &description,
508 double displayDPmm) {
509 double bm_size = -1.0;
511#ifndef ocpnUSE_wxBitmapBundle
513 if (fabs(g_MarkScaleFactorExp - 1.0) > 0.1) {
514 wxBitmap img =
LoadSVG(fileName, -1, -1);
515 bm_size = img.GetWidth() * g_MarkScaleFactorExp;
525 float nominal_legacy_icon_size_pixels = wxMax(4.0, floor(displayDPmm * 12.0));
527 float pix_factor = nominal_legacy_icon_size_pixels / 68.0;
532 bm_size = w * pix_factor * g_MarkScaleFactorExp;
538 w = wxMax(wxMax(w, h), 15);
540 bm_size = w * g_MarkScaleFactorExp;
544 wxBitmap bm =
LoadSVG(fileName, (
int)bm_size, (
int)bm_size);
545 if (!bm.IsOk())
return NULL;
548 LoadSVG(fileName, (
int)bm_size, (
int)bm_size).ConvertToImage();
550 wxRect rClip = CropImageOnAlpha(image);
551 wxImage imageClip = image.GetSubImage(rClip);
558 for (
unsigned int i = 0; i < m_waypoint_man.m_pLegacyIconArray->GetCount();
560 pmi = (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(i);
561 if (pmi->icon_name.IsSameAs(key)) {
563 delete pmi->piconBitmap;
570 pmi->icon_name = key;
571 m_waypoint_man.m_pLegacyIconArray->Add(pmi);
574 pmi->icon_name = key;
575 pmi->icon_description = description;
576 pmi->piconBitmap = NULL;
577 pmi->icon_texture = 0;
578 pmi->preScaled =
false;
579 pmi->iconImage = imageClip;
580 pmi->m_blistImageOK =
false;
585MarkIcon *WayPointmanGui::ProcessExtendedIcon(wxImage &image,
587 const wxString &description) {
593 auto size = m_waypoint_man.m_pExtendedIconArray->GetCount();
594 for (
unsigned int i = 0; i < size; i++) {
595 pmi = (
MarkIcon *)m_waypoint_man.m_pExtendedIconArray->Item(i);
596 if (pmi->icon_name.IsSameAs(key)) {
598 delete pmi->piconBitmap;
605 pmi->icon_name = key;
606 m_waypoint_man.m_pExtendedIconArray->Add(pmi);
609 wxRect rClip = CropImageOnAlpha(image);
610 wxImage imageClip = image.GetSubImage(rClip);
612 pmi->icon_name = key;
613 pmi->icon_description = description;
614 pmi->piconBitmap =
new wxBitmap(imageClip);
615 pmi->icon_texture = 0;
616 pmi->preScaled =
false;
617 pmi->iconImage = imageClip;
618 pmi->m_blistImageOK =
false;
623wxRect WayPointmanGui::CropImageOnAlpha(wxImage &image) {
624 const int w = image.GetWidth();
625 const int h = image.GetHeight();
627 wxRect rv = wxRect(0, 0, w, h);
628 if (!image.HasAlpha())
return rv;
630 unsigned char *pAlpha = image.GetAlpha();
638 for (
int i = 0; i < h; i++) {
639 int lineStartIndex = i * w;
642 while ((j < w) && (pAlpha[lineStartIndex + j] == 0)) j++;
643 leftCrop = wxMin(leftCrop, j);
646 while (k && (pAlpha[lineStartIndex + k] == 0)) k--;
647 rightCrop = wxMin(rightCrop, image.GetWidth() - k - 2);
651 for (
int i = 0; i < w; i++) {
652 int columnStartIndex = i;
655 while ((j < h) && (pAlpha[columnStartIndex + (j * w)] == 0)) j++;
656 topCrop = wxMin(topCrop, j);
659 while (k && (pAlpha[columnStartIndex + (k * w)] == 0)) k--;
660 bottomCrop = wxMin(bottomCrop, h - k - 2);
663 int xcrop = wxMin(rightCrop, leftCrop);
664 int ycrop = wxMin(topCrop, bottomCrop);
665 int crop = wxMin(xcrop, ycrop);
667 rv.x = wxMax(crop, 0);
668 rv.width = wxMax(1, w - (2 * crop));
669 rv.width = wxMin(rv.width, w);
671 rv.height = rv.width;
676void WayPointmanGui::ReloadRoutepointIcons() {
678 for (
RoutePoint *pr : *m_waypoint_man.m_pWayPointList) {
683unsigned int WayPointmanGui::GetIconTexture(
const wxBitmap *pbm,
int &glw,
686 int index = m_waypoint_man.GetIconIndex(pbm);
689 if (!pmi->icon_texture) {
691 wxImage image = pbm->ConvertToImage();
692 unsigned char *d = image.GetData();
698 glGenTextures(1, &pmi->icon_texture);
699 glBindTexture(GL_TEXTURE_2D, pmi->icon_texture);
701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
703 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
705 int w = image.GetWidth(), h = image.GetHeight();
707 pmi->tex_w = NextPow2(w);
708 pmi->tex_h = NextPow2(h);
710 unsigned char *a = image.GetAlpha();
712 unsigned char mr, mg, mb;
713 if (!a) image.GetOrFindMaskColour(&mr, &mg, &mb);
715 unsigned char *e =
new unsigned char[4 * w * h];
716 for (
int y = 0; y < h; y++) {
717 for (
int x = 0; x < w; x++) {
718 unsigned char r, g, b;
719 int off = (y * w + x);
728 a ? a[off] : ((r == mr) && (g == mg) && (b == mb) ? 0 : 255);
732 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pmi->tex_w, pmi->tex_h, 0, GL_RGBA,
733 GL_UNSIGNED_BYTE, NULL);
734 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, e);
742 return pmi->icon_texture;
Extended icon definition.
Represents a waypoint or mark within the navigation system.
Global variables stored in configuration file.
Extern C linked utilities.
PlugIn Object Definition/API.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
Waypoint or mark abstraction.
float g_ChartScaleFactorExp
Global instance.
wxBitmap LoadSVG(const wxString filename, const unsigned int width, const unsigned int height, wxBitmap *default_bitmap, bool use_cache)
Load SVG file and return it's bitmap representation of requested size In case file can't be loaded an...
bool SVGDocumentPixelSize(const wxString filename, unsigned int &width, unsigned int &height)
Return the size of the SVG document in standard 96 DPI pixels https://developer.mozilla....
WaypointMan drawing stuff.