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") {
101 double bm_size_nom = wxMin(wxMax(w, h), floor(displayDPmm * 20));
103 bm_size_nom = wxMax(bm_size_nom, 15);
106 bm_size_nom *= g_MarkScaleFactorExp;
111 if (w != 0 && h != 0) {
116 if (fabs(aspect - 1.0) > .05) {
118 LoadSVG(name, (
int)bm_size_nom, (
int)bm_size_nom, &default_bm)
122 wxRect rClip = CropImageOnAlpha(image);
123 wxImage imageClip = image.GetSubImage(rClip);
124 imageClip.Rescale(bm_size_nom, bm_size_nom / aspect,
125 wxIMAGE_QUALITY_BICUBIC);
126 pmi = ProcessIcon(imageClip, iconname, iconname, g_bUserIconsFirst);
129 const unsigned int bm_size = bm_size_nom;
130 wxImage iconSVG =
LoadSVG(name, bm_size, bm_size, &default_bm,
false)
132 wxRect rClip = CropImageOnAlpha(iconSVG);
133 wxImage imageClip = iconSVG.GetSubImage(rClip);
134 pmi = ProcessIcon(iconSVG, iconname, iconname, g_bUserIconsFirst);
137 if (pmi) pmi->preScaled =
true;
143MarkIcon *WayPointmanGui::ProcessIcon(wxImage image,
const wxString &key,
144 const wxString &description,
151 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
152 pmi = (
MarkIcon *)m_waypoint_man.m_pIconArray->Item(i);
153 if (pmi->icon_name.IsSameAs(key)) {
155 delete pmi->piconBitmap;
162 pmi->icon_name = key;
164 m_waypoint_man.m_pIconArray->Insert(pmi, 0);
166 m_waypoint_man.m_pIconArray->Add(pmi);
170 wxBitmap *pbm =
new wxBitmap(image);
171 pmi->icon_name = key;
172 pmi->icon_description = description;
173 pmi->piconBitmap = NULL;
174 pmi->icon_texture = 0;
175 pmi->preScaled =
false;
176 pmi->iconImage = pbm->ConvertToImage();
177 pmi->m_blistImageOK =
false;
183void WayPointmanGui::ProcessIcons(
ocpnStyle::Style *style,
double displayDPmm) {
184 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
186 delete pmi->piconBitmap;
189 m_waypoint_man.m_pIconArray->Clear();
191 ProcessDefaultIcons(displayDPmm);
197 ProcessUserIcons(style, displayDPmm);
199 if (NULL != m_waypoint_man.pmarkicon_image_list) {
200 m_waypoint_man.pmarkicon_image_list->RemoveAll();
201 delete m_waypoint_man.pmarkicon_image_list;
202 m_waypoint_man.pmarkicon_image_list = NULL;
210 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
212 w = wxMax(w, pmi->iconImage.GetWidth());
213 h = wxMax(h, pmi->iconImage.GetHeight());
216 m_waypoint_man.m_bitmapSizeForList = wxMax(w, h);
217 m_waypoint_man.m_bitmapSizeForList =
218 wxMin(100, m_waypoint_man.m_bitmapSizeForList);
221void WayPointmanGui::ProcessDefaultIcons(
double displayDPmm) {
223 appendOSDirSlash(&iconDir);
224 iconDir.append(
"uidata");
225 appendOSDirSlash(&iconDir);
226 iconDir.append(
"markicons");
227 appendOSDirSlash(&iconDir);
232 if (m_waypoint_man.m_pLegacyIconArray)
233 m_waypoint_man.m_pLegacyIconArray->Clear();
235 m_waypoint_man.m_pLegacyIconArray =
236 new SortedArrayOfMarkIcon(CompareMarkIcons);
238 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Empty.svg",
"empty",
"Empty",
240 if (pmi) pmi->preScaled =
true;
241 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Triangle.svg",
"triangle",
242 "Triangle", displayDPmm);
243 if (pmi) pmi->preScaled =
true;
244 pmi = ProcessLegacyIcon(iconDir +
"1st-Active-Waypoint.svg",
"activepoint",
245 "Active WP", displayDPmm);
246 if (pmi) pmi->preScaled =
true;
247 pmi = ProcessLegacyIcon(iconDir +
"Marks-Boarding-Location.svg",
"boarding",
248 "Boarding Location", displayDPmm);
249 if (pmi) pmi->preScaled =
true;
250 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Airplane.svg",
"airplane",
251 "Airplane", displayDPmm);
252 if (pmi) pmi->preScaled =
true;
253 pmi = ProcessLegacyIcon(iconDir +
"1st-Anchorage.svg",
"anchorage",
254 "Anchorage", displayDPmm);
255 if (pmi) pmi->preScaled =
true;
256 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Anchor2.svg",
"anchor",
"Anchor",
258 if (pmi) pmi->preScaled =
true;
259 pmi = ProcessLegacyIcon(iconDir +
"Marks-Boundary.svg",
"boundary",
260 "Boundary Mark", displayDPmm);
261 if (pmi) pmi->preScaled =
true;
262 pmi = ProcessLegacyIcon(iconDir +
"Marks-Buoy-TypeA.svg",
"buoy1",
263 "buoy Type A", displayDPmm);
264 if (pmi) pmi->preScaled =
true;
265 pmi = ProcessLegacyIcon(iconDir +
"Marks-Buoy-TypeB.svg",
"buoy2",
266 "buoy Type B", displayDPmm);
267 if (pmi) pmi->preScaled =
true;
268 pmi = ProcessLegacyIcon(iconDir +
"Activity-Campfire.svg",
"campfire",
269 "Campfire", displayDPmm);
270 if (pmi) pmi->preScaled =
true;
271 pmi = ProcessLegacyIcon(iconDir +
"Activity-Camping.svg",
"camping",
272 "Camping Spot", displayDPmm);
273 if (pmi) pmi->preScaled =
true;
274 pmi = ProcessLegacyIcon(iconDir +
"Sea-Floor-Coral.svg",
"coral",
"Coral",
276 if (pmi) pmi->preScaled =
true;
277 pmi = ProcessLegacyIcon(iconDir +
"Activity-Fishing.svg",
"fishhaven",
278 "Fish Haven", displayDPmm);
279 if (pmi) pmi->preScaled =
true;
280 pmi = ProcessLegacyIcon(iconDir +
"Activity-Fishing.svg",
"fishing",
281 "Fishing Spot", displayDPmm);
282 if (pmi) pmi->preScaled =
true;
283 pmi = ProcessLegacyIcon(iconDir +
"Activity-Fishing.svg",
"fish",
"Fish",
285 if (pmi) pmi->preScaled =
true;
286 pmi = ProcessLegacyIcon(iconDir +
"Marks-Mooring-Buoy.svg",
"float",
"Float",
288 if (pmi) pmi->preScaled =
true;
289 pmi = ProcessLegacyIcon(iconDir +
"Service-Food.svg",
"food",
"Food",
291 if (pmi) pmi->preScaled =
true;
292 pmi = ProcessLegacyIcon(iconDir +
"Service-Fuel-Pump-Diesel-Petrol.svg",
293 "fuel",
"Fuel", displayDPmm);
294 if (pmi) pmi->preScaled =
true;
295 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Green.svg",
"greenlite",
296 "Green Light", displayDPmm);
297 if (pmi) pmi->preScaled =
true;
298 pmi = ProcessLegacyIcon(iconDir +
"Sea-Floor-Sea-Weed.svg",
"kelp",
"Kelp",
300 if (pmi) pmi->preScaled =
true;
301 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-TypeA.svg",
"light",
302 "Light Type A", displayDPmm);
303 if (pmi) pmi->preScaled =
true;
304 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-TypeB.svg",
"light1",
305 "Light Type B", displayDPmm);
306 if (pmi) pmi->preScaled =
true;
307 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Vessel.svg",
"litevessel",
308 "litevessel", displayDPmm);
309 if (pmi) pmi->preScaled =
true;
310 pmi = ProcessLegacyIcon(iconDir +
"1st-Man-Overboard.svg",
"mob",
"MOB",
312 if (pmi) pmi->preScaled =
true;
313 pmi = ProcessLegacyIcon(iconDir +
"Marks-Mooring-Buoy.svg",
"mooring",
314 "Mooring buoy", displayDPmm);
315 if (pmi) pmi->preScaled =
true;
316 pmi = ProcessLegacyIcon(iconDir +
"Marks-Mooring-Buoy-Super.svg",
"oilbuoy",
317 "Oil buoy", displayDPmm);
318 if (pmi) pmi->preScaled =
true;
319 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Oil-Platform.svg",
"platform",
320 "Platform", displayDPmm);
321 if (pmi) pmi->preScaled =
true;
322 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Red-Green.svg",
"redgreenlite",
323 "Red/Green Light", displayDPmm);
324 if (pmi) pmi->preScaled =
true;
325 pmi = ProcessLegacyIcon(iconDir +
"Marks-Light-Red.svg",
"redlite",
326 "Red Light", displayDPmm);
327 if (pmi) pmi->preScaled =
true;
328 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Rock-Exposed.svg",
"rock1",
329 "Rock (exposed)", displayDPmm);
330 if (pmi) pmi->preScaled =
true;
331 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Rock-Awash.svg",
"rock2",
332 "Rock, (awash)", displayDPmm);
333 if (pmi) pmi->preScaled =
true;
334 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Sandbar.svg",
"sand",
"Sand",
336 if (pmi) pmi->preScaled =
true;
337 pmi = ProcessLegacyIcon(iconDir +
"Activity-Diving-Scuba-Flag.svg",
"scuba",
338 "Scuba", displayDPmm);
339 if (pmi) pmi->preScaled =
true;
340 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Sandbar.svg",
"shoal",
"Shoal",
342 if (pmi) pmi->preScaled =
true;
343 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Snag.svg",
"snag",
"Snag",
345 if (pmi) pmi->preScaled =
true;
346 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Square.svg",
"square",
"Square",
348 if (pmi) pmi->preScaled =
true;
349 pmi = ProcessLegacyIcon(iconDir +
"1st-Diamond.svg",
"diamond",
"Diamond",
351 if (pmi) pmi->preScaled =
true;
352 pmi = ProcessLegacyIcon(iconDir +
"Symbol-Circle.svg",
"circle",
"Circle",
354 if (pmi) pmi->preScaled =
true;
355 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Wreck1.svg",
"wreck1",
"Wreck A",
357 if (pmi) pmi->preScaled =
true;
358 pmi = ProcessLegacyIcon(iconDir +
"Hazard-Wreck2.svg",
"wreck2",
"Wreck B",
360 if (pmi) pmi->preScaled =
true;
361 pmi = ProcessLegacyIcon(iconDir +
"Symbol-X-Small-Blue.svg",
"xmblue",
362 "Blue X", displayDPmm);
363 if (pmi) pmi->preScaled =
true;
364 pmi = ProcessLegacyIcon(iconDir +
"Symbol-X-Small-Green.svg",
"xmgreen",
365 "Green X", displayDPmm);
366 if (pmi) pmi->preScaled =
true;
367 pmi = ProcessLegacyIcon(iconDir +
"Symbol-X-Small-Red.svg",
"xmred",
"Red X",
369 if (pmi) pmi->preScaled =
true;
372 if (m_waypoint_man.m_pExtendedIconArray) {
373 m_waypoint_man.m_pExtendedIconArray->Clear();
375 m_waypoint_man.m_pExtendedIconArray =
376 new SortedArrayOfMarkIcon(CompareMarkIcons);
380 wxArrayString FileList;
383 int n_files = wxDir::GetAllFiles( iconDir, &FileList );
389 for(
int ifile = 0; ifile < n_files; ifile++ ) {
390 wxString name = FileList[ifile];
392 wxFileName fn( name );
394 if( fn.GetExt().Lower() ==
"svg" ) {
395 wxBitmap bmt =
LoadSVG(name, -1, -1 );
402 for(
int ifile = 0; ifile < n_files; ifile++ ) {
403 wxString name = FileList[ifile];
405 wxFileName fn( name );
406 wxString iconname = fn.GetName();
408 if( fn.GetExt().Lower() ==
"svg" ) {
409 wxImage iconSVG =
LoadSVG( name, (
int)bm_size, (
int)bm_size );
410 MarkIcon * pmi = ProcessExtendedIcon( iconSVG, iconname, iconname );
412 pmi->preScaled =
true;
417 wxArrayString FileList;
419 double bm_size = wxMax(4.0, floor(displayDPmm * 12.0));
421 bm_size *= g_MarkScaleFactorExp;
423 int n_files = wxDir::GetAllFiles(iconDir, &FileList);
427 for (
int ifile = 0; ifile < n_files; ifile++) {
428 wxString name = FileList[ifile];
431 wxString iconname = fn.GetName();
434 if (fn.GetExt().Lower() ==
"svg") {
440 w = wxMax(wxMax(w, h), 15);
441 bm_size = w * g_MarkScaleFactorExp;
450 float nominal_legacy_icon_size_pixels =
451 wxMax(4.0, floor(displayDPmm * 12.0));
453 float pix_factor = nominal_legacy_icon_size_pixels / 68.0;
454 bm_size *= pix_factor;
457 wxBitmap bmp =
LoadSVG(name, (
int)bm_size, (
int)bm_size);
459 wxImage iconSVG = bmp.ConvertToImage();
461 MarkIcon *pmi = ProcessExtendedIcon(iconSVG, iconname, iconname);
462 if (pmi) pmi->preScaled =
true;
464 wxLogMessage(
"Failed loading mark icon " + name);
473 auto size = m_waypoint_man.m_pLegacyIconArray->GetCount();
474 for (
unsigned int i = 0; i < size; i++) {
475 pmi = (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(i);
476 m_waypoint_man.m_pIconArray->Add(pmi);
479 size = m_waypoint_man.m_pExtendedIconArray->GetCount();
480 for (
unsigned int i = 0; i < size; i++) {
481 pmi = (
MarkIcon *)m_waypoint_man.m_pExtendedIconArray->Item(i);
486 auto legacy_count = m_waypoint_man.m_pLegacyIconArray->GetCount();
487 for (
unsigned int j = 0; j < legacy_count; j++) {
489 (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(j);
490 if (pmiLegacy->icon_name.IsSameAs(pmi->icon_name)) {
495 if (!noAdd) m_waypoint_man.m_pIconArray->Add(pmi);
499void WayPointmanGui::ReloadAllIcons(
double displayDPmm) {
500 ProcessIcons(g_StyleManager->GetCurrentStyle(), displayDPmm);
502 for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
505 if (m_waypoint_man.m_cs == GLOBAL_COLOR_SCHEME_DUSK) {
506 dim_image = m_waypoint_man.CreateDimImage(pmi->iconImage, .50);
507 pmi->iconImage = dim_image;
508 }
else if (m_waypoint_man.m_cs == GLOBAL_COLOR_SCHEME_NIGHT) {
509 dim_image = m_waypoint_man.CreateDimImage(pmi->iconImage, .20);
510 pmi->iconImage = dim_image;
513 ReloadRoutepointIcons();
516void WayPointmanGui::SetColorScheme(ColorScheme cs,
double displayDPmm) {
517 m_waypoint_man.m_cs = cs;
518 ReloadAllIcons(displayDPmm);
521MarkIcon *WayPointmanGui::ProcessLegacyIcon(wxString fileName,
523 const wxString &description,
524 double displayDPmm) {
525 double bm_size = -1.0;
527#ifndef ocpnUSE_wxBitmapBundle
529 if (fabs(g_MarkScaleFactorExp - 1.0) > 0.1) {
530 wxBitmap img =
LoadSVG(fileName, -1, -1);
531 bm_size = img.GetWidth() * g_MarkScaleFactorExp;
541 float nominal_legacy_icon_size_pixels = wxMax(4.0, floor(displayDPmm * 12.0));
543 float pix_factor = nominal_legacy_icon_size_pixels / 68.0;
548 bm_size = w * pix_factor * g_MarkScaleFactorExp;
554 w = wxMax(wxMax(w, h), 15);
556 bm_size = w * g_MarkScaleFactorExp;
560 wxBitmap bm =
LoadSVG(fileName, (
int)bm_size, (
int)bm_size);
561 if (!bm.IsOk())
return NULL;
564 LoadSVG(fileName, (
int)bm_size, (
int)bm_size).ConvertToImage();
566 wxRect rClip = CropImageOnAlpha(image);
567 wxImage imageClip = image.GetSubImage(rClip);
574 for (
unsigned int i = 0; i < m_waypoint_man.m_pLegacyIconArray->GetCount();
576 pmi = (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(i);
577 if (pmi->icon_name.IsSameAs(key)) {
579 delete pmi->piconBitmap;
586 pmi->icon_name = key;
587 m_waypoint_man.m_pLegacyIconArray->Add(pmi);
590 pmi->icon_name = key;
591 pmi->icon_description = description;
592 pmi->piconBitmap = NULL;
593 pmi->icon_texture = 0;
594 pmi->preScaled =
false;
595 pmi->iconImage = imageClip;
596 pmi->m_blistImageOK =
false;
601MarkIcon *WayPointmanGui::ProcessExtendedIcon(wxImage &image,
603 const wxString &description) {
609 auto size = m_waypoint_man.m_pExtendedIconArray->GetCount();
610 for (
unsigned int i = 0; i < size; i++) {
611 pmi = (
MarkIcon *)m_waypoint_man.m_pExtendedIconArray->Item(i);
612 if (pmi->icon_name.IsSameAs(key)) {
614 delete pmi->piconBitmap;
621 pmi->icon_name = key;
622 m_waypoint_man.m_pExtendedIconArray->Add(pmi);
625 wxRect rClip = CropImageOnAlpha(image);
626 wxImage imageClip = image.GetSubImage(rClip);
628 pmi->icon_name = key;
629 pmi->icon_description = description;
630 pmi->piconBitmap =
new wxBitmap(imageClip);
631 pmi->icon_texture = 0;
632 pmi->preScaled =
false;
633 pmi->iconImage = imageClip;
634 pmi->m_blistImageOK =
false;
639wxRect WayPointmanGui::CropImageOnAlpha(wxImage &image) {
640 const int w = image.GetWidth();
641 const int h = image.GetHeight();
643 wxRect rv = wxRect(0, 0, w, h);
644 if (!image.HasAlpha())
return rv;
646 unsigned char *pAlpha = image.GetAlpha();
654 for (
int i = 0; i < h; i++) {
655 int lineStartIndex = i * w;
658 while ((j < w) && (pAlpha[lineStartIndex + j] == 0)) j++;
659 leftCrop = wxMin(leftCrop, j);
662 while (k && (pAlpha[lineStartIndex + k] == 0)) k--;
663 rightCrop = wxMin(rightCrop, image.GetWidth() - k - 2);
667 for (
int i = 0; i < w; i++) {
668 int columnStartIndex = i;
671 while ((j < h) && (pAlpha[columnStartIndex + (j * w)] == 0)) j++;
672 topCrop = wxMin(topCrop, j);
675 while (k && (pAlpha[columnStartIndex + (k * w)] == 0)) k--;
676 bottomCrop = wxMin(bottomCrop, h - k - 2);
679 int xcrop = wxMin(rightCrop, leftCrop);
680 int ycrop = wxMin(topCrop, bottomCrop);
681 int crop = wxMin(xcrop, ycrop);
683 rv.x = wxMax(crop, 0);
684 rv.width = wxMax(1, w - (2 * crop));
685 rv.width = wxMin(rv.width, w);
687 rv.height = rv.width;
692void WayPointmanGui::ReloadRoutepointIcons() {
694 for (
RoutePoint *pr : *m_waypoint_man.m_pWayPointList) {
699unsigned int WayPointmanGui::GetIconTexture(
const wxBitmap *pbm,
int &glw,
702 int index = m_waypoint_man.GetIconIndex(pbm);
705 if (!pmi->icon_texture) {
707 wxImage image = pbm->ConvertToImage();
708 unsigned char *d = image.GetData();
714 glGenTextures(1, &pmi->icon_texture);
715 glBindTexture(GL_TEXTURE_2D, pmi->icon_texture);
717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
721 int w = image.GetWidth(), h = image.GetHeight();
723 pmi->tex_w = NextPow2(w);
724 pmi->tex_h = NextPow2(h);
726 unsigned char *a = image.GetAlpha();
728 unsigned char mr, mg, mb;
729 if (!a) image.GetOrFindMaskColour(&mr, &mg, &mb);
731 unsigned char *e =
new unsigned char[4 * w * h];
732 for (
int y = 0; y < h; y++) {
733 for (
int x = 0; x < w; x++) {
734 unsigned char r, g, b;
735 int off = (y * w + x);
744 a ? a[off] : ((r == mr) && (g == mg) && (b == mb) ? 0 : 255);
748 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pmi->tex_w, pmi->tex_h, 0, GL_RGBA,
749 GL_UNSIGNED_BYTE, NULL);
750 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, e);
758 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.