Exemplo n.º 1
0
void Topology::updateCache(rectObj thebounds, bool purgeonly) {
  if (!triggerUpdateCache) return;

  if (!shapefileopen) return;

  in_scale = CheckScale();

  if (!in_scale) {
    // not visible, so flush the cache
    // otherwise we waste time on looking up which shapes are in bounds
    flushCache();
    triggerUpdateCache = false;
    in_scale_last = false;
    return;
  }

  if (purgeonly) {
    in_scale_last = in_scale;
    return;
  }

  triggerUpdateCache = false;

#ifdef DEBUG_TFC
#ifdef TOPOFASTCACHE
  StartupStore(TEXT("---UpdateCache() starts, mode%d%s"),cache_mode,NEWLINE);
#else
  StartupStore(TEXT("---UpdateCache() starts, original code%s"),NEWLINE);
#endif
  int starttick = GetTickCount();
#endif

#ifdef TOPOFASTCACHE
  if(msRectOverlap(&shpfile.bounds, &thebounds) != MS_TRUE) {
    // this happens if entire shape is out of range
    // so clear buffer.
    flushCache();
    in_scale_last = in_scale;
    return;
  }

  bool smaller = false;
  bool bigger = false;
  bool in_scale_again = in_scale && !in_scale_last;
  int shapes_loaded = 0;
  shapes_visible_count = 0;
  in_scale_last = in_scale;
  
  switch (cache_mode) {
    case 0: // Original code plus one special case
      smaller = (msRectContained(&thebounds, &lastBounds) == MS_TRUE);
      if (smaller) { //Special case, search inside, we don't need to load additional shapes, just remove
        shapes_visible_count = 0;
        for (int i=0; i<shpfile.numshapes; i++) {
          if (shpCache[i]) {
            if(msRectOverlap(&(shpCache[i]->shape.bounds), &thebounds) != MS_TRUE) {
              removeShape(i);
            } else shapes_visible_count++;
          }
        }//for
      } else { 
        //In this case we have to run the original algoritm
        msSHPWhichShapes(&shpfile, thebounds, 0);
        shapes_visible_count = 0;
        for (int i=0; i<shpfile.numshapes; i++) {
          if (msGetBit(shpfile.status, i)) {
            if (shpCache[i]==NULL) {
              // shape is now in range, and wasn't before
              shpCache[i] = addShape(i);
              shapes_loaded++;
            }
            shapes_visible_count++;
          } else {
            removeShape(i);
          }
        }//for
      }
      break;

    case 1:  // Bounds array in memory
      bigger = (msRectContained(&lastBounds, &thebounds) == MS_TRUE);
      smaller = (msRectContained(&thebounds, &lastBounds) == MS_TRUE);
      if (bigger || in_scale_again) { //We don't need to remove shapes, just load, so skip loaded ones
        for (int i=0; i<shpfile.numshapes; i++) {
          if (shpCache[i]) continue;
          if(msRectOverlap(&shpBounds[i], &thebounds) == MS_TRUE) {
            // shape is now in range, and wasn't before
            shpCache[i] = addShape(i);
            shapes_loaded++;
          }
        }//for
        shapes_visible_count+=shapes_loaded;
      } else
      if (smaller) { //Search inside, we don't need to load additional shapes, just remove
        for (int i=0; i<shpfile.numshapes; i++) {
          if (shpCache[i]==NULL) continue;
          if(msRectOverlap(&shpBounds[i], &thebounds) != MS_TRUE) {
            removeShape(i);
          } else shapes_visible_count++;
        }//for
      } else { 
        //Otherwise we have to search the all array
        for (int i=0; i<shpfile.numshapes; i++) {
          if(msRectOverlap(&shpBounds[i], &thebounds) == MS_TRUE) {
            if (shpCache[i]==NULL) {
              // shape is now in range, and wasn't before
              shpCache[i] = addShape(i);
              shapes_loaded++;
            }
            shapes_visible_count++;
          } else {
            removeShape(i);
          }
        }//for
      }
      break;

    case 2: // All shapes in memory	
      XShape *pshp;
      shapes_visible_count = 0;
      for (int i=0; i<shpfile.numshapes; i++) {
        pshp = shps[i];
        if(msRectOverlap(&(pshp->shape.bounds), &thebounds) == MS_TRUE) {
          shpCache[i] = pshp;
          shapes_visible_count++;
        } else {
          shpCache[i] = NULL;
        }
      }//for
      break;
    }//sw

    lastBounds = thebounds;
#else

  msSHPWhichShapes(&shpfile, thebounds, 0);
  if (!shpfile.status) {
    // this happens if entire shape is out of range
    // so clear buffer.
    flushCache();
    return;
  }

  shapes_visible_count = 0;

  for (int i=0; i<shpfile.numshapes; i++) {

    if (msGetBit(shpfile.status, i)) {
      
      if (shpCache[i]==NULL) {
	// shape is now in range, and wasn't before
	shpCache[i] = addShape(i);
      }
      shapes_visible_count++;
    } else {
      removeShape(i);
    }
  }
#endif

#ifdef DEBUG_TFC
  long free_size = CheckFreeRam();
  StartupStore(TEXT("   UpdateCache() ends, shps_visible=%d ram=%li (%dms)%s"),shapes_visible_count, free_size, GetTickCount()-starttick,NEWLINE);
#endif
}
Exemplo n.º 2
0
void Topology::TriggerIfScaleNowVisible(void) {
  triggerUpdateCache |= (CheckScale() != in_scale);
}
Exemplo n.º 3
0
void Topology::TriggerIfScaleNowVisible(MapWindowProjection &map_projection) {
  triggerUpdateCache |= (CheckScale(map_projection.GetMapScaleUser()) != in_scale);
}
Exemplo n.º 4
0
double MLIFont::GetLineDescent()
{
    EnsureUIThread();
    CheckScale();
    return (double)TTF_FontDescent(pTtfFont) / GetFontScale();
}
Exemplo n.º 5
0
void MLIFont::DrawInternal(const string &s, Vector2 position, Color color, double scale, RectangleWH clipRect)
{
    EnsureUIThread();

    // If we're trying to draw an empty string, we can just return -
    // we're not gonna draw anything anyhow.
    if (s.length() == 0)
    {
        return;
    }

    CheckScale();

    double x = position.GetX();
    double y = position.GetY();

    for (string::const_iterator it = s.begin(); it < s.end();)
    {
        uint32_t c = 0;
        if (!GetNextFromStringIterator(it, s.end(), &c))
        {
            break;
        }

        Image *pGlyphImage = cache[c];
        if (pGlyphImage == NULL)
        {
            continue;
        }

        RectangleWH characterClipRect(0, 0, pGlyphImage->width / GetFontScale(), pGlyphImage->height / GetFontScale());
        RectangleWH originalCharacterClipRect = characterClipRect;

        if (clipRect.GetWidth() < 0 || clipRect.GetX() < originalCharacterClipRect.GetWidth())
        {
            if (clipRect.GetWidth() >= 0)
            {
                if (clipRect.GetX() > 0)
                {
                    characterClipRect.SetX(originalCharacterClipRect.GetX() + clipRect.GetX());
                    characterClipRect.SetWidth(originalCharacterClipRect.GetWidth() - clipRect.GetX());
                }

                if (clipRect.GetWidth() < characterClipRect.GetWidth())
                {
                    characterClipRect.SetWidth(clipRect.GetWidth());
                }

                if (clipRect.GetY() > 0)
                {
                    characterClipRect.SetY(min(originalCharacterClipRect.GetY() + clipRect.GetY(), originalCharacterClipRect.GetY() + originalCharacterClipRect.GetHeight()));
                    characterClipRect.SetHeight(originalCharacterClipRect.GetHeight() - (characterClipRect.GetY() - originalCharacterClipRect.GetY()));
                }

                if (clipRect.GetHeight() < characterClipRect.GetHeight())
                {
                    characterClipRect.SetHeight(clipRect.GetHeight());
                }
            }

            if (characterClipRect.GetWidth() > 0 && characterClipRect.GetHeight() > 0)
            {
                characterClipRect.SetHeight(characterClipRect.GetHeight() * GetFontScale());
                characterClipRect.SetWidth(characterClipRect.GetWidth() * GetFontScale());
                pGlyphImage->Draw(Vector2(x, y), characterClipRect, false, false, scale, scale, color);
            }
        }

        double deltaX = pGlyphImage->width;

        if (it < s.end())
        {
            uint32_t c2 = 0;
            if (PeekNextFromStringIterator(it, s.end(), &c2))
            {
                deltaX = GetKernedWidth(c, c2);
            }
        }

        x += deltaX / GetFontScale();
    }
}
Exemplo n.º 6
0
Image *MLIFont::RenderGlyph(uint32_t c)
{
    EnsureUIThread();
    CheckScale();

    // render char
    SDL_Color whiteColor = {255, 255, 255, 255};
    if (invertedColors)
    {
        whiteColor.b = 255 - whiteColor.b;
        whiteColor.g = 255 - whiteColor.g;
        whiteColor.a = 255 - whiteColor.a;
    }

    string utf8string;
    utf8::unchecked::append(c, back_inserter(utf8string));

    SDL_Surface *pSurface = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), whiteColor);
    if (pSurface == NULL)
    {
        return NULL;
    }

    int scaledStrokeWidth = strokeWidth * GetFontScale() + 0.5;

    // render outlines
    if (strokeWidth > 0)
    {
        SDL_Color blackColor = {0, 0, 0, 255};
        if (invertedColors)
        {
            blackColor.b = 255 - blackColor.b;
            blackColor.g = 255 - blackColor.g;
            blackColor.a = 255 - blackColor.a;
        }

#ifndef MLI_SDL_FONT_OUTLINING
        SDL_Surface *pSurfaceOutline = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor);

        SDL_Surface *pSurfaceOutlinedText = SDL_CreateRGBSurface(
                    0,
                    pSurface->w + scaledStrokeWidth * 2,
                    pSurface->h + scaledStrokeWidth * 2,
                    pSurface->format->BitsPerPixel,
                    pSurface->format->Rmask,
                    pSurface->format->Gmask,
                    pSurface->format->Bmask,
                    pSurface->format->Amask);

        SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND);

        SDL_Rect dstRect = {0, 0, pSurface->w, pSurface->h};

        for (dstRect.x = 0; dstRect.x <= scaledStrokeWidth * 2; dstRect.x++)
        {
            for (dstRect.y = 0; dstRect.y <= scaledStrokeWidth * 2; dstRect.y++)
            {
                SDL_BlitSurface(pSurfaceOutline, NULL, pSurfaceOutlinedText, &dstRect);
            }
        }

        dstRect.x = scaledStrokeWidth;
        dstRect.y = scaledStrokeWidth;
        SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND);
        SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect);

        SDL_FreeSurface(pSurface);
        SDL_FreeSurface(pSurfaceOutline);

        pSurface = pSurfaceOutlinedText;
#else
        TTF_SetFontOutline(pTtfFont, scaledStrokeWidth);

        SDL_Surface *pSurfaceOutlinedText = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor);

        SDL_SetSurfaceBlendMode(pSurfaceOutlinedText, SDL_BLENDMODE_BLEND);
        SDL_Rect dstRect = {scaledStrokeWidth, scaledStrokeWidth, pSurface->w, pSurface->h};
        SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect);

        SDL_FreeSurface(pSurface);

        pSurface = pSurfaceOutlinedText;

        TTF_SetFontOutline(pTtfFont, 0);
#endif
    }

    // create image
    Image *pImage = Image::Load(pSurface, true);
    pImage->FlagFontSource(this);
    pImage->SetUseScreenScaling(false);

    return pImage;
}