Example #1
0
void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    m_stops.append(stop);

    m_stopsSorted = false;
    platformDestroy();

    invalidateHash();
}
Example #2
0
void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    m_stops.append(stop);

    m_stopsSorted = false;
    destroyShader();

    invalidateHash();
}
Example #3
0
void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    if (m_gradientSpaceTransformation == gradientSpaceTransformation)
        return;

    m_gradientSpaceTransformation = gradientSpaceTransformation;
    setPlatformGradientSpaceTransform(gradientSpaceTransformation);

    invalidateHash();
}
Example #4
0
void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    if (m_gradientSpaceTransformation == gradientSpaceTransformation)
        return;

    m_gradientSpaceTransformation = gradientSpaceTransformation;
    if (m_gradient)
        m_gradient->setLocalMatrix(m_gradientSpaceTransformation);

    invalidateHash();
}
Example #5
0
void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(m_gradient == 0);

    if (m_spreadMethod == spreadMethod)
        return;

    m_spreadMethod = spreadMethod;

    invalidateHash();
}
Example #6
0
void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);

    invalidateHash();
}
Example #7
0
void Gradient::addColorStop(float value, const Color& color)
{
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    destroyShader();

    invalidateHash();
}
Example #8
0
void Gradient::addColorStop(float value, const Color& color)
{
    // FIXME: ExtendedColor - update this to support colors with color spaces.
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    platformDestroy();

    invalidateHash();
}
Example #9
0
Variant HHVM_FUNCTION(wordwrap, const String& str, int64_t linewidth /* = 75 */,
                      const String& brk /* = s_nl */, bool cut /* = false */) {
  const char* brkstr = brk.data();
  size_t textlen = str.size();
  size_t brklen = brk.size();

  if (textlen == 0) {
    return empty_string();
  }
  if (brklen == 0) {
    raise_warning("Break string cannot be empty");
    return false;
  }
  if (linewidth == 0 && cut) {
    raise_warning("Can't force cut when width is zero");
    return false;
  }
  size_t w = linewidth >= 0 ? linewidth : 0;

  // If the string's length is less than or equal to the specified
  // width, there's nothing to do and we can just return the string.
  if (textlen <= w) return str;

  // Special case for a single-character break as it needs no
  // additional storage space
  if (brklen == 1 && !cut) {
    auto new_sd = StringData::Make(str.get(), CopyString);
    new_sd->invalidateHash();
    Variant ret = new_sd;
    auto const bs = new_sd->bufferSlice();
    char* newtext = bs.begin();
    auto bc = brkstr[0];
    size_t current = 0, laststart = 0, lastspace = 0;
    for (; current < textlen; current++) {
      if (newtext[current] == bc) {
        laststart = lastspace = current + 1;
      } else if (newtext[current] == ' ') {
        if (current - laststart >= w) {
          newtext[current] = bc;
          laststart = current + 1;
        }
        lastspace = current;
      } else if (current - laststart >= w && laststart != lastspace) {
        newtext[lastspace] = bc;
        laststart = lastspace + 1;
      }
    }
    return ret;
  }

  // Multiple character line break or forced cut

  // Estimate how big the output string will be. It's okay if this estimate
  // is wrong as we will grow or shrink as needed. The goals here are two-
  // fold: (1) avoid the need to grow or shrink in the common case, and
  // (2) for extreme cases where it's hard to make an accurate estimate
  // (ex. when w is very small or brk is very large) we should be careful
  // to avoid making huge over-estimations.
  StringBuffer strbuf(
    textlen +
    textlen / (std::max<size_t>(w, 16) - 8) * std::min<size_t>(brklen, 8));

  const char* text = str.data();
  size_t current = 0, laststart = 0, lastspace = 0;
  for (; current < textlen; current++) {
    // when we hit an existing break, copy to new buffer, and
    // fix up laststart and lastspace
    if (text[current] == brkstr[0] && current + brklen < textlen &&
        !strncmp(text + current, brkstr, brklen)) {
      strbuf.append(text + laststart, current - laststart + brklen);
      current += brklen - 1;
      laststart = lastspace = current + 1;
    }
    // if it is a space, check if it is at the line boundary,
    // copy and insert a break, or just keep track of it
    else if (text[current] == ' ') {
      if (current - laststart >= w) {
        strbuf.append(text + laststart, current - laststart);
        strbuf.append(brkstr, brklen);
        laststart = current + 1;
      }
      lastspace = current;
    }
    // if we are cutting, and we've accumulated enough
    // characters, and we haven't see a space for this line,
    // copy and insert a break.
    else if (current - laststart >= w && cut && laststart >= lastspace) {
      strbuf.append(text + laststart, current - laststart);
      strbuf.append(brkstr, brklen);
      laststart = lastspace = current;
    }
    // if the current word puts us over width w, copy back up
    // until the last space, insert a break, and move up the
    // laststart
    else if (current - laststart >= w && laststart < lastspace) {
      strbuf.append(text + laststart, lastspace - laststart);
      strbuf.append(brkstr, brklen);
      laststart = lastspace = lastspace + 1;
    }
  }
  // copy over any stragglers
  if (laststart != current) {
    strbuf.append(text + laststart, current - laststart);
  }

  auto s = strbuf.detach();

  // if it's not possible to reduce the output string's capacity by more
  // than 25%, then we can just return the string as is.
  size_t estShrinkCap =
    MemoryManager::estimateSmartCap(sizeof(StringData) + s.size() + 1);
  if (estShrinkCap * 4 >= (size_t)s.capacity() * 3) {
    return s;
  }
  // reallocate into a smaller buffer so that we don't waste memory
  return StringData::Make(s.get(), CopyString);
}