27#if defined(__ANDROID__) 
   29#include <GL/gl_private.h>   
   32#elif defined(ocpnUSE_GL) 
   38#elif defined(__WXOSX__) 
   40#include <OpenGL/glu.h> 
   41typedef void (*_GLUfuncptr)();
 
   42#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 
   44#elif defined(__WXQT__) || defined(__WXGTK__) 
   53#include <wx/filename.h> 
   59#include "model/base_platform.h" 
   60#include "model/cutil.h" 
   61#include "model/MarkIcon.h" 
   62#include "model/route_point.h" 
   65#include "waypointman_gui.h" 
   69extern float g_MarkScaleFactorExp;
 
   71extern bool g_bUserIconsFirst;
 
   74  return (mi1->icon_name.CmpNoCase(mi2->icon_name));
 
   80  msg.Printf(_T(
"DPMM: %g   ScaleFactorExp: %g"), displayDPmm,
 
   81             g_MarkScaleFactorExp);
 
   85  wxChar sep = wxFileName::GetPathSeparator();
 
   86  if (UserIconPath.Last() != sep) UserIconPath.Append(sep);
 
   87  UserIconPath.Append(_T(
"UserIcons/"));
 
   89  wxLogMessage(_T(
"Looking for UserIcons at ") + UserIconPath);
 
   91  if (wxDir::Exists(UserIconPath)) {
 
   92    wxLogMessage(_T(
"Loading UserIcons from ") + UserIconPath);
 
   93    wxArrayString FileList;
 
   95    wxBitmap default_bm = wxBitmap(1, 1);  
 
   98        wxDir::GetAllFiles(UserIconPath, &FileList, _T(
""), wxDIR_FILES);
 
  100    for (
int ifile = 0; ifile < n_files; ifile++) {
 
  102          g_bUserIconsFirst ? FileList[n_files - ifile - 1] : FileList[ifile];
 
  105      wxString iconname = fn.GetName();
 
  107      if (fn.GetExt().Lower() == _T(
"xpm")) {
 
  108        if (icon1.LoadFile(name, wxBITMAP_TYPE_XPM)) {
 
  109          wxLogMessage(_T(
"Adding icon: ") + iconname);
 
  110          wxImage image = icon1.ConvertToImage();
 
  111          ProcessIcon(image, iconname, iconname, g_bUserIconsFirst);
 
  114      if (fn.GetExt().Lower() == _T(
"png")) {
 
  115        if (icon1.LoadFile(name, wxBITMAP_TYPE_PNG)) {
 
  116          wxLogMessage(_T(
"Adding icon: ") + iconname);
 
  117          wxImage image = icon1.ConvertToImage();
 
  118          ProcessIcon(image, iconname, iconname, g_bUserIconsFirst);
 
  121      if (fn.GetExt().Lower() == _T(
"svg")) {
 
  123        SVGDocumentPixelSize(name, w, h);
 
  127        double bm_size_nom = wxMin(wxMax(w, h), floor(displayDPmm * 20));
 
  129        bm_size_nom = wxMax(bm_size_nom, 15);
 
  132        bm_size_nom *= g_MarkScaleFactorExp;
 
  137        if (w != 0 && h != 0) {
 
  142        if (fabs(aspect - 1.0) > .05) {
 
  144              LoadSVG(name, (
int)bm_size_nom, (
int)bm_size_nom, &default_bm)
 
  148            wxRect rClip = CropImageOnAlpha(image);
 
  149            wxImage imageClip = image.GetSubImage(rClip);
 
  150            imageClip.Rescale(bm_size_nom, bm_size_nom / aspect,
 
  151                              wxIMAGE_QUALITY_BICUBIC);
 
  152            pmi = ProcessIcon(imageClip, iconname, iconname, g_bUserIconsFirst);
 
  155          const unsigned int bm_size = bm_size_nom;  
 
  156          wxImage iconSVG = LoadSVG(name, bm_size, bm_size, &default_bm, 
false)
 
  158          wxRect rClip = CropImageOnAlpha(iconSVG);
 
  159          wxImage imageClip = iconSVG.GetSubImage(rClip);
 
  160          pmi = ProcessIcon(iconSVG, iconname, iconname, g_bUserIconsFirst);
 
  163        if (pmi) pmi->preScaled = 
true;
 
  169MarkIcon *WayPointmanGui::ProcessIcon(wxImage image, 
const wxString &key,
 
  170                                      const wxString &description,
 
  177  for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
 
  178    pmi = (
MarkIcon *)m_waypoint_man.m_pIconArray->Item(i);
 
  179    if (pmi->icon_name.IsSameAs(key)) {
 
  181      delete pmi->piconBitmap;
 
  188    pmi->icon_name = key;  
 
  190      m_waypoint_man.m_pIconArray->Insert(pmi, 0);
 
  192      m_waypoint_man.m_pIconArray->Add(pmi);
 
  196  wxBitmap *pbm = 
new wxBitmap(image);
 
  197  pmi->icon_name = key;
 
  198  pmi->icon_description = description;
 
  199  pmi->piconBitmap = NULL;
 
  200  pmi->icon_texture = 0; 
 
  201  pmi->preScaled = 
false;
 
  202  pmi->iconImage = pbm->ConvertToImage();
 
  203  pmi->m_blistImageOK = 
false;
 
  209void WayPointmanGui::ProcessIcons(
ocpnStyle::Style *style, 
double displayDPmm) {
 
  210  for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
 
  212    delete pmi->piconBitmap;
 
  215  m_waypoint_man.m_pIconArray->Clear();
 
  217  ProcessDefaultIcons(displayDPmm);
 
  223  ProcessUserIcons(style, displayDPmm);
 
  225  if (NULL != m_waypoint_man.pmarkicon_image_list) {
 
  226    m_waypoint_man.pmarkicon_image_list->RemoveAll();
 
  227    delete m_waypoint_man.pmarkicon_image_list;
 
  228    m_waypoint_man.pmarkicon_image_list = NULL;
 
  236  for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
 
  238    w = wxMax(w, pmi->iconImage.GetWidth());
 
  239    h = wxMax(h, pmi->iconImage.GetHeight());
 
  242  m_waypoint_man.m_bitmapSizeForList = wxMax(w, h);
 
  243  m_waypoint_man.m_bitmapSizeForList =
 
  244      wxMin(100, m_waypoint_man.m_bitmapSizeForList);
 
  247void WayPointmanGui::ProcessDefaultIcons(
double displayDPmm) {
 
  248  wxString iconDir = g_BasePlatform->GetSharedDataDir();
 
  249  appendOSDirSlash(&iconDir);
 
  250  iconDir.append(_T(
"uidata"));
 
  251  appendOSDirSlash(&iconDir);
 
  252  iconDir.append(_T(
"markicons"));
 
  253  appendOSDirSlash(&iconDir);
 
  258  if (m_waypoint_man.m_pLegacyIconArray)
 
  259    m_waypoint_man.m_pLegacyIconArray->Clear();
 
  261    m_waypoint_man.m_pLegacyIconArray =
 
  262        new SortedArrayOfMarkIcon(CompareMarkIcons);
 
  264  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-Empty.svg"), _T(
"empty"),
 
  265                          _T(
"Empty"), displayDPmm);
 
  266  if (pmi) pmi->preScaled = 
true;
 
  267  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-Triangle.svg"), _T(
"triangle"),
 
  268                          _T(
"Triangle"), displayDPmm);
 
  269  if (pmi) pmi->preScaled = 
true;
 
  270  pmi = ProcessLegacyIcon(iconDir + _T(
"1st-Active-Waypoint.svg"),
 
  271                          _T(
"activepoint"), _T(
"Active WP"), displayDPmm);
 
  272  if (pmi) pmi->preScaled = 
true;
 
  273  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Boarding-Location.svg"),
 
  274                          _T(
"boarding"), _T(
"Boarding Location"), displayDPmm);
 
  275  if (pmi) pmi->preScaled = 
true;
 
  276  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Airplane.svg"), _T(
"airplane"),
 
  277                          _T(
"Airplane"), displayDPmm);
 
  278  if (pmi) pmi->preScaled = 
true;
 
  279  pmi = ProcessLegacyIcon(iconDir + _T(
"1st-Anchorage.svg"), _T(
"anchorage"),
 
  280                          _T(
"Anchorage"), displayDPmm);
 
  281  if (pmi) pmi->preScaled = 
true;
 
  282  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-Anchor2.svg"), _T(
"anchor"),
 
  283                          _T(
"Anchor"), displayDPmm);
 
  284  if (pmi) pmi->preScaled = 
true;
 
  285  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Boundary.svg"), _T(
"boundary"),
 
  286                          _T(
"Boundary Mark"), displayDPmm);
 
  287  if (pmi) pmi->preScaled = 
true;
 
  288  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Buoy-TypeA.svg"), _T(
"bouy1"),
 
  289                          _T(
"Bouy Type A"), displayDPmm);
 
  290  if (pmi) pmi->preScaled = 
true;
 
  291  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Buoy-TypeB.svg"), _T(
"bouy2"),
 
  292                          _T(
"Bouy Type B"), displayDPmm);
 
  293  if (pmi) pmi->preScaled = 
true;
 
  294  pmi = ProcessLegacyIcon(iconDir + _T(
"Activity-Campfire.svg"), _T(
"campfire"),
 
  295                          _T(
"Campfire"), displayDPmm);
 
  296  if (pmi) pmi->preScaled = 
true;
 
  297  pmi = ProcessLegacyIcon(iconDir + _T(
"Activity-Camping.svg"), _T(
"camping"),
 
  298                          _T(
"Camping Spot"), displayDPmm);
 
  299  if (pmi) pmi->preScaled = 
true;
 
  300  pmi = ProcessLegacyIcon(iconDir + _T(
"Sea-Floor-Coral.svg"), _T(
"coral"),
 
  301                          _T(
"Coral"), displayDPmm);
 
  302  if (pmi) pmi->preScaled = 
true;
 
  303  pmi = ProcessLegacyIcon(iconDir + _T(
"Activity-Fishing.svg"), _T(
"fishhaven"),
 
  304                          _T(
"Fish Haven"), displayDPmm);
 
  305  if (pmi) pmi->preScaled = 
true;
 
  306  pmi = ProcessLegacyIcon(iconDir + _T(
"Activity-Fishing.svg"), _T(
"fishing"),
 
  307                          _T(
"Fishing Spot"), displayDPmm);
 
  308  if (pmi) pmi->preScaled = 
true;
 
  309  pmi = ProcessLegacyIcon(iconDir + _T(
"Activity-Fishing.svg"), _T(
"fish"),
 
  310                          _T(
"Fish"), displayDPmm);
 
  311  if (pmi) pmi->preScaled = 
true;
 
  312  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Mooring-Buoy.svg"), _T(
"float"),
 
  313                          _T(
"Float"), displayDPmm);
 
  314  if (pmi) pmi->preScaled = 
true;
 
  315  pmi = ProcessLegacyIcon(iconDir + _T(
"Service-Food.svg"), _T(
"food"),
 
  316                          _T(
"Food"), displayDPmm);
 
  317  if (pmi) pmi->preScaled = 
true;
 
  318  pmi = ProcessLegacyIcon(iconDir + _T(
"Service-Fuel-Pump-Diesel-Petrol.svg"),
 
  319                          _T(
"fuel"), _T(
"Fuel"), displayDPmm);
 
  320  if (pmi) pmi->preScaled = 
true;
 
  321  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Light-Green.svg"),
 
  322                          _T(
"greenlite"), _T(
"Green Light"), displayDPmm);
 
  323  if (pmi) pmi->preScaled = 
true;
 
  324  pmi = ProcessLegacyIcon(iconDir + _T(
"Sea-Floor-Sea-Weed.svg"), _T(
"kelp"),
 
  325                          _T(
"Kelp"), displayDPmm);
 
  326  if (pmi) pmi->preScaled = 
true;
 
  327  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Light-TypeA.svg"), _T(
"light"),
 
  328                          _T(
"Light Type A"), displayDPmm);
 
  329  if (pmi) pmi->preScaled = 
true;
 
  330  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Light-TypeB.svg"), _T(
"light1"),
 
  331                          _T(
"Light Type B"), displayDPmm);
 
  332  if (pmi) pmi->preScaled = 
true;
 
  333  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Light-Vessel.svg"),
 
  334                          _T(
"litevessel"), _T(
"litevessel"), displayDPmm);
 
  335  if (pmi) pmi->preScaled = 
true;
 
  336  pmi = ProcessLegacyIcon(iconDir + _T(
"1st-Man-Overboard.svg"), _T(
"mob"),
 
  337                          _T(
"MOB"), displayDPmm);
 
  338  if (pmi) pmi->preScaled = 
true;
 
  339  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Mooring-Buoy.svg"), _T(
"mooring"),
 
  340                          _T(
"Mooring Bouy"), displayDPmm);
 
  341  if (pmi) pmi->preScaled = 
true;
 
  342  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Mooring-Buoy-Super.svg"),
 
  343                          _T(
"oilbouy"), _T(
"Oil Bouy"), displayDPmm);
 
  344  if (pmi) pmi->preScaled = 
true;
 
  345  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Oil-Platform.svg"),
 
  346                          _T(
"platform"), _T(
"Platform"), displayDPmm);
 
  347  if (pmi) pmi->preScaled = 
true;
 
  349      ProcessLegacyIcon(iconDir + _T(
"Marks-Light-Red-Green.svg"),
 
  350                        _T(
"redgreenlite"), _T(
"Red/Green Light"), displayDPmm);
 
  351  if (pmi) pmi->preScaled = 
true;
 
  352  pmi = ProcessLegacyIcon(iconDir + _T(
"Marks-Light-Red.svg"), _T(
"redlite"),
 
  353                          _T(
"Red Light"), displayDPmm);
 
  354  if (pmi) pmi->preScaled = 
true;
 
  355  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Rock-Exposed.svg"), _T(
"rock1"),
 
  356                          _T(
"Rock (exposed)"), displayDPmm);
 
  357  if (pmi) pmi->preScaled = 
true;
 
  358  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Rock-Awash.svg"), _T(
"rock2"),
 
  359                          _T(
"Rock, (awash)"), displayDPmm);
 
  360  if (pmi) pmi->preScaled = 
true;
 
  361  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Sandbar.svg"), _T(
"sand"),
 
  362                          _T(
"Sand"), displayDPmm);
 
  363  if (pmi) pmi->preScaled = 
true;
 
  364  pmi = ProcessLegacyIcon(iconDir + _T(
"Activity-Diving-Scuba-Flag.svg"),
 
  365                          _T(
"scuba"), _T(
"Scuba"), displayDPmm);
 
  366  if (pmi) pmi->preScaled = 
true;
 
  367  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Sandbar.svg"), _T(
"shoal"),
 
  368                          _T(
"Shoal"), displayDPmm);
 
  369  if (pmi) pmi->preScaled = 
true;
 
  370  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Snag.svg"), _T(
"snag"),
 
  371                          _T(
"Snag"), displayDPmm);
 
  372  if (pmi) pmi->preScaled = 
true;
 
  373  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-Square.svg"), _T(
"square"),
 
  374                          _T(
"Square"), displayDPmm);
 
  375  if (pmi) pmi->preScaled = 
true;
 
  376  pmi = ProcessLegacyIcon(iconDir + _T(
"1st-Diamond.svg"), _T(
"diamond"),
 
  377                          _T(
"Diamond"), displayDPmm);
 
  378  if (pmi) pmi->preScaled = 
true;
 
  379  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-Circle.svg"), _T(
"circle"),
 
  380                          _T(
"Circle"), displayDPmm);
 
  381  if (pmi) pmi->preScaled = 
true;
 
  382  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Wreck1.svg"), _T(
"wreck1"),
 
  383                          _T(
"Wreck A"), displayDPmm);
 
  384  if (pmi) pmi->preScaled = 
true;
 
  385  pmi = ProcessLegacyIcon(iconDir + _T(
"Hazard-Wreck2.svg"), _T(
"wreck2"),
 
  386                          _T(
"Wreck B"), displayDPmm);
 
  387  if (pmi) pmi->preScaled = 
true;
 
  388  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-X-Small-Blue.svg"), _T(
"xmblue"),
 
  389                          _T(
"Blue X"), displayDPmm);
 
  390  if (pmi) pmi->preScaled = 
true;
 
  391  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-X-Small-Green.svg"),
 
  392                          _T(
"xmgreen"), _T(
"Green X"), displayDPmm);
 
  393  if (pmi) pmi->preScaled = 
true;
 
  394  pmi = ProcessLegacyIcon(iconDir + _T(
"Symbol-X-Small-Red.svg"), _T(
"xmred"),
 
  395                          _T(
"Red X"), displayDPmm);
 
  396  if (pmi) pmi->preScaled = 
true;
 
  399  if (m_waypoint_man.m_pExtendedIconArray) {
 
  400    m_waypoint_man.m_pExtendedIconArray->Clear();
 
  402    m_waypoint_man.m_pExtendedIconArray =
 
  403        new SortedArrayOfMarkIcon(CompareMarkIcons);
 
  407    wxArrayString FileList;
 
  410    int n_files = wxDir::GetAllFiles( iconDir, &FileList );
 
  414    if( fabs(g_ChartScaleFactorExp - 1.0) > 0.1){
 
  416        for( 
int ifile = 0; ifile < n_files; ifile++ ) {
 
  417            wxString name = FileList[ifile];
 
  419            wxFileName fn( name );
 
  421            if( fn.GetExt().Lower() == _T(
"svg") ) {
 
  422                wxBitmap bmt = LoadSVG(name, -1, -1 );
 
  423                bm_size = bmt.GetWidth() * g_ChartScaleFactorExp;
 
  429    for( 
int ifile = 0; ifile < n_files; ifile++ ) {
 
  430        wxString name = FileList[ifile];
 
  432        wxFileName fn( name );
 
  433        wxString iconname = fn.GetName();
 
  435        if( fn.GetExt().Lower() == _T(
"svg") ) {
 
  436            wxImage iconSVG = LoadSVG( name, (
int)bm_size, (
int)bm_size );
 
  437            MarkIcon * pmi = ProcessExtendedIcon( iconSVG, iconname, iconname );
 
  439                pmi->preScaled = 
true;
 
  444  wxArrayString FileList;
 
  446  double bm_size = wxMax(4.0, floor(displayDPmm * 12.0));
 
  448  bm_size *= g_MarkScaleFactorExp;
 
  450  int n_files = wxDir::GetAllFiles(iconDir, &FileList);
 
  452  g_BasePlatform->ShowBusySpinner();
 
  454  for (
int ifile = 0; ifile < n_files; ifile++) {
 
  455    wxString name = FileList[ifile];
 
  458    wxString iconname = fn.GetName();
 
  461    if (fn.GetExt().Lower() == _T(
"svg")) {
 
  464      SVGDocumentPixelSize(name, w, h);
 
  467      w = wxMax(wxMax(w, h), 15);
 
  468      bm_size = w * g_MarkScaleFactorExp;
 
  471      wxBitmap bmp = LoadSVG(name, (
int)bm_size, (
int)bm_size);
 
  473        wxImage iconSVG = bmp.ConvertToImage();
 
  475        MarkIcon *pmi = ProcessExtendedIcon(iconSVG, iconname, iconname);
 
  476        if (pmi) pmi->preScaled = 
true;
 
  478        wxLogMessage(
"Failed loading mark icon " + name);
 
  482  g_BasePlatform->HideBusySpinner();
 
  487  auto size = m_waypoint_man.m_pLegacyIconArray->GetCount();
 
  488  for (
unsigned int i = 0; i < size; i++) {
 
  489    pmi = (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(i);
 
  490    m_waypoint_man.m_pIconArray->Add(pmi);
 
  493  size = m_waypoint_man.m_pExtendedIconArray->GetCount();
 
  494  for (
unsigned int i = 0; i < size; i++) {
 
  495    pmi = (
MarkIcon *)m_waypoint_man.m_pExtendedIconArray->Item(i);
 
  500    auto legacy_count = m_waypoint_man.m_pLegacyIconArray->GetCount();
 
  501    for (
unsigned int j = 0; j < legacy_count; j++) {
 
  503          (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(j);
 
  504      if (pmiLegacy->icon_name.IsSameAs(pmi->icon_name)) {
 
  509    if (!noAdd) m_waypoint_man.m_pIconArray->Add(pmi);
 
  513void WayPointmanGui::ReloadAllIcons(
double displayDPmm) {
 
  514  ProcessIcons(g_StyleManager->GetCurrentStyle(), displayDPmm);
 
  516  for (
unsigned int i = 0; i < m_waypoint_man.m_pIconArray->GetCount(); i++) {
 
  519    if (m_waypoint_man.m_cs == GLOBAL_COLOR_SCHEME_DUSK) {
 
  520      dim_image = m_waypoint_man.CreateDimImage(pmi->iconImage, .50);
 
  521      pmi->iconImage = dim_image;
 
  522    } 
else if (m_waypoint_man.m_cs == GLOBAL_COLOR_SCHEME_NIGHT) {
 
  523      dim_image = m_waypoint_man.CreateDimImage(pmi->iconImage, .20);
 
  524      pmi->iconImage = dim_image;
 
  527  ReloadRoutepointIcons();
 
  530void WayPointmanGui::SetColorScheme(ColorScheme cs, 
double displayDPmm) {
 
  531  m_waypoint_man.m_cs = cs;
 
  532  ReloadAllIcons(displayDPmm);
 
  535MarkIcon *WayPointmanGui::ProcessLegacyIcon(wxString fileName,
 
  537                                            const wxString &description,
 
  538                                            double displayDPmm) {
 
  539  double bm_size = -1.0;
 
  541#ifndef ocpnUSE_wxBitmapBundle 
  543  if (fabs(g_MarkScaleFactorExp - 1.0) > 0.1) {
 
  544    wxBitmap img = LoadSVG(fileName, -1, -1);
 
  545    bm_size = img.GetWidth() * g_MarkScaleFactorExp;
 
  555  float nominal_legacy_icon_size_pixels = wxMax(4.0, floor(displayDPmm * 12.0));
 
  557  float pix_factor = nominal_legacy_icon_size_pixels / 68.0;
 
  560  SVGDocumentPixelSize(fileName, w, h);
 
  562  bm_size = w * pix_factor * g_MarkScaleFactorExp;
 
  567  SVGDocumentPixelSize(fileName, w, h);
 
  568  w = wxMax(wxMax(w, h), 15);  
 
  570  bm_size = w * g_MarkScaleFactorExp;  
 
  574  wxBitmap bm = LoadSVG(fileName, (
int)bm_size, (
int)bm_size);
 
  575  if (!bm.IsOk()) 
return NULL;
 
  578      LoadSVG(fileName, (
int)bm_size, (
int)bm_size).ConvertToImage();
 
  580  wxRect rClip = CropImageOnAlpha(image);
 
  581  wxImage imageClip = image.GetSubImage(rClip);
 
  588  for (
unsigned int i = 0; i < m_waypoint_man.m_pLegacyIconArray->GetCount();
 
  590    pmi = (
MarkIcon *)m_waypoint_man.m_pLegacyIconArray->Item(i);
 
  591    if (pmi->icon_name.IsSameAs(key)) {
 
  593      delete pmi->piconBitmap;
 
  600    pmi->icon_name = key;  
 
  601    m_waypoint_man.m_pLegacyIconArray->Add(pmi);
 
  604  pmi->icon_name = key;
 
  605  pmi->icon_description = description;
 
  606  pmi->piconBitmap = NULL;
 
  607  pmi->icon_texture = 0; 
 
  608  pmi->preScaled = 
false;
 
  609  pmi->iconImage = imageClip;
 
  610  pmi->m_blistImageOK = 
false;
 
  615MarkIcon *WayPointmanGui::ProcessExtendedIcon(wxImage &image,
 
  617                                              const wxString &description) {
 
  623  auto size = m_waypoint_man.m_pExtendedIconArray->GetCount();
 
  624  for (
unsigned int i = 0; i < size; i++) {
 
  625    pmi = (
MarkIcon *)m_waypoint_man.m_pExtendedIconArray->Item(i);
 
  626    if (pmi->icon_name.IsSameAs(key)) {
 
  628      delete pmi->piconBitmap;
 
  635    pmi->icon_name = key;  
 
  636    m_waypoint_man.m_pExtendedIconArray->Add(pmi);
 
  639  wxRect rClip = CropImageOnAlpha(image);
 
  640  wxImage imageClip = image.GetSubImage(rClip);
 
  642  pmi->icon_name = key;
 
  643  pmi->icon_description = description;
 
  644  pmi->piconBitmap = 
new wxBitmap(imageClip);
 
  645  pmi->icon_texture = 0; 
 
  646  pmi->preScaled = 
false;
 
  647  pmi->iconImage = imageClip;
 
  648  pmi->m_blistImageOK = 
false;
 
  653wxRect WayPointmanGui::CropImageOnAlpha(wxImage &image) {
 
  654  const int w = image.GetWidth();
 
  655  const int h = image.GetHeight();
 
  657  wxRect rv = wxRect(0, 0, w, h);
 
  658  if (!image.HasAlpha()) 
return rv;
 
  660  unsigned char *pAlpha = image.GetAlpha();
 
  668  for (
int i = 0; i < h; i++) {
 
  669    int lineStartIndex = i * w;
 
  672    while ((j < w) && (pAlpha[lineStartIndex + j] == 0)) j++;
 
  673    leftCrop = wxMin(leftCrop, j);
 
  676    while (k && (pAlpha[lineStartIndex + k] == 0)) k--;
 
  677    rightCrop = wxMin(rightCrop, image.GetWidth() - k - 2);
 
  681  for (
int i = 0; i < w; i++) {
 
  682    int columnStartIndex = i;
 
  685    while ((j < h) && (pAlpha[columnStartIndex + (j * w)] == 0)) j++;
 
  686    topCrop = wxMin(topCrop, j);
 
  689    while (k && (pAlpha[columnStartIndex + (k * w)] == 0)) k--;
 
  690    bottomCrop = wxMin(bottomCrop, h - k - 2);
 
  693  int xcrop = wxMin(rightCrop, leftCrop);
 
  694  int ycrop = wxMin(topCrop, bottomCrop);
 
  695  int crop = wxMin(xcrop, ycrop);
 
  697  rv.x = wxMax(crop, 0);
 
  698  rv.width = wxMax(1, w - (2 * crop));
 
  699  rv.width = wxMin(rv.width, w);
 
  701  rv.height = rv.width;
 
  706void WayPointmanGui::ReloadRoutepointIcons() {
 
  709  wxRoutePointListNode *node = m_waypoint_man.m_pWayPointList->GetFirst();
 
  713    node = node->GetNext();
 
  717unsigned int WayPointmanGui::GetIconTexture(
const wxBitmap *pbm, 
int &glw,
 
  720  int index = m_waypoint_man.GetIconIndex(pbm);
 
  723  if (!pmi->icon_texture) {
 
  725    wxImage image = pbm->ConvertToImage();
 
  726    unsigned char *d = image.GetData();
 
  732    glGenTextures(1, &pmi->icon_texture);
 
  733    glBindTexture(GL_TEXTURE_2D, pmi->icon_texture);
 
  735    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
  736    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
  737    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
  739    int w = image.GetWidth(), h = image.GetHeight();
 
  741    pmi->tex_w = NextPow2(w);
 
  742    pmi->tex_h = NextPow2(h);
 
  744    unsigned char *a = image.GetAlpha();
 
  746    unsigned char mr, mg, mb;
 
  747    if (!a) image.GetOrFindMaskColour(&mr, &mg, &mb);
 
  749    unsigned char *e = 
new unsigned char[4 * w * h];
 
  750    for (
int y = 0; y < h; y++) {
 
  751      for (
int x = 0; x < w; x++) {
 
  752        unsigned char r, g, b;
 
  753        int off = (y * w + x);
 
  762            a ? a[off] : ((r == mr) && (g == mg) && (b == mb) ? 0 : 255);
 
  766    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pmi->tex_w, pmi->tex_h, 0, GL_RGBA,
 
  767                 GL_UNSIGNED_BYTE, NULL);
 
  768    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, e);
 
  776  return pmi->icon_texture;
 
Represents a waypoint or mark within the navigation system.
PlugIn Object Definition/API.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.