Beispiel #1
0
void luv2rgb(int *RGB,float *LUV,int size)
{
  int i,k;
  double x,y,X,Y,Z,den,u2,v2,X0,Z0,Y0,u20,v20,vec[3];

  X0 = (0.607+0.174+0.201);
  Y0 = (0.299+0.587+0.114);
  Z0 = (      0.066+1.117);

/* Y0 = 1.0 */
  u20 = 4*X0/(X0+15*Y0+3*Z0);
  v20 = 9*Y0/(X0+15*Y0+3*Z0);

  for (i=0;i<size;i+=3)
  {
    if (LUV[i]>0)
    {
      if (LUV[i]<8.0) Y=((double) LUV[i])/903.3;
      else Y=pow(( ((double) LUV[i]) +16)/116.0,3.0);
      u2=((double) LUV[i+1])/13.0/((double) LUV[i])+u20;
      v2=((double) LUV[i+2])/13.0/((double) LUV[i])+v20;

      den = 6+3*u2-8*v2;
      if (den<0) printf("den<0\n");
      if (den==0) printf("den==0\n");
      x = 4.5*u2/den;
      y = 2.0*v2/den;

      X=x/y*Y;
      Z=(1-x-y)/y*Y;
    }
    else { X=0.0; Y=0.0; Z=0.0; }

    vec[0] = ( 3.240479*X-1.537150*Y-0.498536*Z);
    vec[1] = (-0.969256*X+1.875992*Y+0.041556*Z);
    vec[2] = ( 0.055648*X-0.204043*Y+1.057311*Z);
    for (k=0;k<3;k++)
    {
      if  (vec[k]<=0.018) vec[k] = 255*4.5*vec[k];
      else vec[k] = 255*(1.099*pow(vec[k],0.45)-0.099);
      if (vec[k]>255) vec[k] = 255;
      else if (vec[k]<0) vec[k] = 0;
      RGB[i+k] = lroundf((float)vec[k]);
    }
  }
}
Beispiel #2
0
static void output_mode_cb(void *data, struct wl_output *output,
                           uint32_t flags, int32_t width, int32_t height,
                           int32_t refresh)
{
    demux_t *demux = data;
    demux_sys_t *sys = demux->p_sys;

    msg_Dbg(demux, "output mode: 0x%08"PRIX32" %"PRId32"x%"PRId32
            " %"PRId32"mHz%s", flags, width, height, refresh,
            (flags & WL_OUTPUT_MODE_CURRENT) ? " (current)" : "");

    if (!(flags & WL_OUTPUT_MODE_CURRENT))
        return;
    if (width <= sys->x || height <= sys->y)
        return;

    if (sys->es != NULL)
        es_out_Del(demux->out, sys->es);

    es_format_t fmt;

    es_format_Init(&fmt, VIDEO_ES, VLC_CODEC_RGB32);
    fmt.video.i_chroma = VLC_CODEC_RGB32;
    fmt.video.i_bits_per_pixel = 32;
    fmt.video.i_sar_num = fmt.video.i_sar_den = 1;
    fmt.video.i_frame_rate = lroundf(1000.f * sys->rate);
    fmt.video.i_frame_rate_base = 1000;
    fmt.video.i_width = width;

    if (sys->w != 0 && width > sys->w + sys->x)
        fmt.video.i_visible_width = sys->w;
    else
        fmt.video.i_visible_width = width - sys->x;

    if (sys->h != 0 && height > sys->h + sys->y)
        fmt.video.i_visible_height = sys->h;
    else
        fmt.video.i_visible_height = height - sys->y;

    fmt.video.i_height = fmt.video.i_visible_height;

    sys->es = es_out_Add(demux->out, &fmt);
    sys->width = width;
    sys->height = height;
    (void) output;
}
void Font::drawComplexText(GraphicsContext* graphicsContext,
    const TextRunPaintInfo& runInfo,
    const FloatPoint& point) const
{
    UniscribeHelperTextRun state(runInfo.run, *this);

    SkColor color = graphicsContext->effectiveFillColor();
    unsigned char alpha = SkColorGetA(color);
    // Skip 100% transparent text; no need to draw anything.
    if (!alpha && graphicsContext->strokeStyle() == NoStroke)
        return;

    HDC hdc = 0;
    // Uniscribe counts the coordinates from the upper left, while WebKit uses
    // the baseline, so we have to subtract off the ascent.
    state.draw(graphicsContext, primaryFont()->platformData(), hdc, lroundf(point.x()), lroundf(point.y() - fontMetrics().ascent()), runInfo.bounds, runInfo.from, runInfo.to);
}
Beispiel #4
0
static block_t *Fl32toS32(filter_t *filter, block_t *b)
{
    float   *src = (float *)b->p_buffer;
    int32_t *dst = (int32_t *)src;
    for (size_t i = b->i_buffer / 4; i--;)
    {
        float s = *(src++) * 2147483648.f;
        if (s >= 2147483647.f)
            *(dst++) = 2147483647;
        else
        if (s <= -2147483648.f)
            *(dst++) = -2147483648;
        else
            *(dst++) = lroundf(s);
    }
    VLC_UNUSED(filter);
    return b;
}
Beispiel #5
0
/*** from FL32 ***/
static block_t *Fl32toU8(filter_t *filter, block_t *b)
{
    float   *src = (float *)b->p_buffer;
    uint8_t *dst = (uint8_t *)src;
    for (size_t i = b->i_buffer / 4; i--;)
    {
        float s = *(src++) * 128.f;
        if (s >= 127.f)
            *(dst++) = 255;
        else
        if (s <= -128.f)
            *(dst++) = 0;
        else
            *(dst++) = lroundf(s) + 128;
    }
    b->i_buffer /= 4;
    VLC_UNUSED(filter);
    return b;
}
Beispiel #6
0
void AudioInput::setMaxBandwidth(int bytespersec) {
	int audiorate;
	int baserate;

	void *es;
	es = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));

	float f = static_cast<float>(g.s.iQuality);

	do {
		speex_encoder_ctl(es, SPEEX_SET_VBR_QUALITY, &f);
		speex_encoder_ctl(es, SPEEX_GET_BITRATE, &baserate);
		audiorate = baserate;

		audiorate /= 400/g.s.iFramesPerPacket;

		// Overhead
		audiorate += 20 + 8 + 4 + 3 + 1 + 2;

		if (g.s.bTransmitPosition)
			audiorate += 12;

		if (NetworkConfig::TcpModeEnabled())
			audiorate += 12;

		audiorate = (audiorate * 50) / g.s.iFramesPerPacket;

		if (f <= 1.9)
			break;

		if (audiorate > bytespersec) {
			f -= 1.0f;
		}
	} while (audiorate > bytespersec);

	speex_encoder_destroy(es);

	speex_encoder_ctl(esEncState, SPEEX_SET_VBR_QUALITY, &f);
	speex_encoder_ctl(esEncState, SPEEX_SET_VBR_MAX_BITRATE, &baserate);

	g.iAudioBandwidth = audiorate;
	g.iAudioQuality = lroundf(f);
}
Beispiel #7
0
static void *Thread(void *data)
{
    demux_t *demux = data;
    demux_sys_t *sys = demux->p_sys;
    struct wl_display *display = sys->display;
    struct pollfd ufd[1];
    unsigned interval = lroundf(CLOCK_FREQ / (sys->rate * 1000.f));

    int canc = vlc_savecancel();
    vlc_cleanup_push(cleanup_wl_display_read, display);

    ufd[0].fd = wl_display_get_fd(display);
    ufd[0].events = POLLIN;

    for (;;)
    {
        if (DisplayError(demux, display))
            break;

        if (sys->es != NULL)
        {
            block_t *block = Shoot(demux);

            block->i_pts = block->i_dts = vlc_tick_now();
            es_out_SetPCR(demux->out, block->i_pts);
            es_out_Send(demux->out, sys->es, block);
        }

        while (wl_display_prepare_read(display) != 0)
            wl_display_dispatch_pending(display);
        wl_display_flush(display);
        vlc_restorecancel(canc);

        while (poll(ufd, 1, interval) < 0);

        canc = vlc_savecancel();
        wl_display_read_events(display);
        wl_display_dispatch_pending(display);
    }
    vlc_cleanup_pop();
    vlc_restorecancel(canc);
    return NULL;
}
Beispiel #8
0
static int VolumeSet(dtaudio_output_t *aout, float vol)
{
    aout_sys_t *sys = (aout_sys_t)aout->ao_priv;
    if (!sys->volumeItf)
        return -1;

    /* Convert UI volume to linear factor (cube) */
    vol = vol * vol * vol;

    /* millibels from linear amplification */
    int mb = lroundf(2000.f * log10f(vol));
    if (mb < SL_MILLIBEL_MIN)
        mb = SL_MILLIBEL_MIN;
    else if (mb > 0)
        mb = 0; /* maximum supported level could be higher: GetMaxVolumeLevel */

    SLresult r = SetVolumeLevel(aout->sys->volumeItf, mb);
    return (r == SL_RESULT_SUCCESS) ? 0 : -1;
}
Beispiel #9
0
void dump2byte(int fpp, float *fbuf, int size)
{
  int i;
  static short int obuf[FFTLEN/NNODE];
  float fmax,ftmp;

  while (size>FFTLEN/NNODE-2) {
    fmax=0;
    for (i=0;i<FFTLEN/NNODE;i++) fmax=MAX(fmax,fabs(fbuf[i]));
    for (i=0;i<FFTLEN/NNODE;i++) {
      ftmp=sqrt(fabs(fbuf[i]/fmax));
      ftmp=(fbuf[i]>0)?ftmp:-ftmp;
      obuf[i]=lroundf(32767*ftmp);
    }
    if (write(fpp,&fmax,sizeof(float)) != sizeof(float)) perror("dump1byte:write");
    if (write(fpp,obuf,sizeof(short int)*FFTLEN/NNODE) != sizeof(short int)*FFTLEN/NNODE ) perror("dump2byte:write");
    fbuf+=FFTLEN/NNODE;
    size-=FFTLEN/NNODE;
  }
}
Beispiel #10
0
void dump1bytefsall(int fpp, float *fbuf, int size)
{
  int i;
#define MAXBUF (NCROSS*ONEGATE)
  static char obuf[FFTLENOUT];
  float fmax,ftmp;

  while (size>FFTLENOUT-2) {
    fmax=0;
    for (i=0;i<FFTLENOUT;i++) fmax=MAX(fmax,fabs(fbuf[i]));
    for (i=0;i<FFTLENOUT;i++) {
      ftmp=sqrt(fabs(fbuf[i]/fmax));
      ftmp=(fbuf[i]>0)?ftmp:-ftmp;
      obuf[i]=lroundf(127*ftmp);
    }
    if (write(fpp,&fmax,sizeof(float)) != sizeof(float)) perror("dump1byte:write");
    if (write(fpp,obuf,FFTLENOUT) != FFTLENOUT ) perror("dump1byte:write");
    fbuf+=FFTLENOUT;
    size-=FFTLENOUT;
  }
}
Beispiel #11
0
struct svgtiny_shape *svgtiny_add_shape(struct svgtiny_parse_state *state)
{
	struct svgtiny_shape *shape = (svgtiny_shape *) realloc(state->diagram->shape,
			(state->diagram->shape_count + 1) * sizeof (state->diagram->shape[0]));
	if (!shape)
		return 0;
	state->diagram->shape = shape;

	shape += state->diagram->shape_count;
	shape->path = 0;
	shape->path_length = 0;
	shape->text = 0;
	shape->fill = state->fill;
	shape->stroke = state->stroke;
	shape->stroke_width = lroundf((float) state->stroke_width *
			(state->ctm.a + state->ctm.d) / 2.0);
	if (0 < state->stroke_width && shape->stroke_width == 0)
		shape->stroke_width = 1;

	return shape;
}
void
simpleaudio_tone_init( unsigned int new_sin_table_len, float mag )
{
    sin_table_len = new_sin_table_len;
    tone_mag = mag;

    if ( sin_table_len != 0 ) {
	sin_table_short = realloc(sin_table_short, sin_table_len * sizeof(short));
	sin_table_float = realloc(sin_table_float, sin_table_len * sizeof(float));
	if ( !sin_table_short || !sin_table_float ) {
	    perror("malloc");
	    assert(0);
	}

	unsigned int i;
	unsigned short mag_s = 32767.0f * tone_mag + 0.5f;
	if ( tone_mag > 1.0f ) // clamp to 1.0 to avoid overflow
	    mag_s = 32767;
	if ( mag_s < 1 ) // "short epsilon"
	    mag_s = 1;
	for ( i=0; i<sin_table_len; i++ )
	    sin_table_short[i] = lroundf( mag_s * sinf((float)M_PI*2*i/sin_table_len) );
	for ( i=0; i<sin_table_len; i++ )
	    sin_table_float[i] = tone_mag * sinf((float)M_PI*2*i/sin_table_len);

    } else {
	if ( sin_table_short ) {
	    free(sin_table_short);
	    sin_table_short = NULL;
	}
	if ( sin_table_float ) {
	    free(sin_table_float);
	    sin_table_float = NULL;
	}
    }
}
Beispiel #13
0
void 
set_pswf_tables(
    float C, int nt, float lambda, const float *coefs, 
    int ltbl, int linv, float* wtbl, float* winv)                                            
{
    // Set up lookup tables for convolvent (used in Phase 1 of   
    // do_recon()), and for the final correction factor (used in 
    // Phase 3).

    int i;
    float norm;
    const float fac = (float)ltbl / (linv+0.5);
    const float polyz = legendre(nt, coefs, 0.);

    wtbl[0] = 1.0;
    for(i=1; i<=ltbl; i++) 
    {   
        wtbl[i] = legendre(nt, coefs, (float)i/ltbl) / polyz;
    }

    // Note the final result at end of Phase 3 contains the factor, 
    // norm^2.  This incorporates the normalization of the 2D
    // inverse FFT in Phase 2 as well as scale factors involved
    // in the inverse Fourier transform of the convolvent.
    norm = sqrt(M_PI/2/C/lambda) / 1.2;

    winv[linv] = norm / wtbl[0];
    for(i=1; i<=linv; i++)
    {
        // Minus sign for alternate entries
        // corrects for "natural" data layout
        // in array H at end of Phase 1.
        norm = -norm; 
        winv[linv+i] = winv[linv-i] = norm / wtbl[lroundf(i*fac)];
    }
}
Beispiel #14
0
void dump1byte_test(int fpp, float *fbuf, int size)
{
#define MAXBUF (NCROSS*ONEGATE)
  int i;
  struct {float fmax; char obuf[FFTLEN/NNODE]} outbuf[size/(FFTLEN/NNODE)];
  static char obuf[FFTLEN/NNODE];
  float fmax,ftmp;
  int k=0;

  while (size>FFTLEN/NNODE-2) {
    fmax=0;
    for (i=0;i<FFTLEN/NNODE;i++) fmax=MAX(fmax,fabs(fbuf[i]));
    outbuf[k].fmax=fmax;
    for (i=0;i<FFTLEN/NNODE;i++) {
      ftmp=sqrt(fabs(fbuf[i]/fmax));
      ftmp=(fbuf[i]>0)?ftmp:-ftmp;
      outbuf[k].obuf[i]=lroundf(127*ftmp);
    }
    k++;
    fbuf+=FFTLEN/NNODE;
    size-=FFTLEN/NNODE;
  }
  if (write(fpp,outbuf,sizeof(outbuf))!=sizeof(outbuf)) perror("dump1byte:write");
}
Beispiel #15
0
void GPSNmea::ProcessGPGGA(uint8_t *pData) {
    uint8_t pField[MAXFIELD];
    char pBuff[10];

    // Time (currently not used)
    /*if (GetField(pData, pField, 0, MAXFIELD)) {
        // Hour
        pBuff[0] = pField[0];
        pBuff[1] = pField[1];
        pBuff[2] = '\0';
        data.hours = atoi(pBuff);

        // minute
        pBuff[0] = pField[2];
        pBuff[1] = pField[3];
        pBuff[2] = '\0';
        data.minutes = atoi(pBuff);

        // Second
        pBuff[0] = pField[4];
        pBuff[1] = pField[5];
        pBuff[2] = '\0';
        data.seconds = atoi(pBuff);
    } */

    // Latitude (currently not used)
    /*if (GetField(pData, pField, 1, MAXFIELD)) {
        data.latitude = lroundf(10000000 * atof((char *) pField + 2) / 60.0);
        pField[2] = '\0';
        data.latitude += lroundf(10000000 * atof((char *) pField));

    }
    if (GetField(pData, pField, 2, MAXFIELD)) {
        if (pField[0] == 'S')
            data.latitude = -data.latitude;
    }

    // Longitude (currently not used)
    if (GetField(pData, pField, 3, MAXFIELD)) {
        data.longitude = lroundf(10000000 * atof((char *) pField + 3) / 60.0);
        pField[3] = '\0';
        data.longitude += lroundf(10000000 * atof((char *) pField));
    }
    if (GetField(pData, pField, 4, MAXFIELD)) {
        if (pField[0] == 'W')
            data.longitude = -data.longitude;
    } */

    // Satellites in use
    if (GetField(pData, pField, 6, MAXFIELD)) {
        pBuff[0] = pField[0];
        pBuff[1] = pField[1];
        pBuff[2] = '\0';
        data.trackedSats = atoi(pBuff);
    }

    // HDOP
    if (GetField(pData, pField, 7, MAXFIELD)) {
        data.dop = lroundf(atof((CHAR *) pField) * 10); // FIXME: is this the right units?
    }

    // Altitude
    if (GetField(pData, pField, 8, MAXFIELD)) {
        data.altitude = lroundf(atof((CHAR *) pField) * 100);
    }

    // Set the data-ready flag.
    this->dataReadyFlag = true;
}
Beispiel #16
0
void Font::drawGlyphs(GraphicsContext* graphicsContext,
                      const SimpleFontData* font,
                      const GlyphBuffer& glyphBuffer,
                      int from,
                      int numGlyphs,
                      const FloatPoint& point) const
{
    SkColor color = graphicsContext->effectiveFillColor();
    unsigned char alpha = SkColorGetA(color);
    // Skip 100% transparent text; no need to draw anything.
    if (!alpha && graphicsContext->strokeStyle() == NoStroke && !graphicsContext->hasShadow())
        return;

    // We draw the glyphs in chunks to avoid having to do a heap allocation for
    // the arrays of characters and advances.
    const int kMaxBufferLength = 256;
    Vector<int, kMaxBufferLength> advances;
    int glyphIndex = 0;  // The starting glyph of the current chunk.

    float horizontalOffset = point.x(); // The floating point offset of the left side of the current glyph.
#if ENABLE(OPENTYPE_VERTICAL)
    const OpenTypeVerticalData* verticalData = font->verticalData();
    if (verticalData) {
        Vector<FloatPoint, kMaxBufferLength> translations;
        Vector<GOFFSET, kMaxBufferLength> offsets;

        // Skia doesn't have matrix for glyph coordinate space, so we rotate back the CTM.
        AffineTransform savedMatrix = graphicsContext->getCTM();
        graphicsContext->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
        graphicsContext->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));

        const FontMetrics& metrics = font->fontMetrics();
        SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAscent() - metrics.floatAscent(IdeographicBaseline));
        while (glyphIndex < numGlyphs) {
            // How many chars will be in this chunk?
            int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);

            const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
            translations.resize(curLen);
            verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], curLen, reinterpret_cast<float*>(&translations[0]));
            // To position glyphs vertically, we use offsets instead of advances.
            advances.resize(curLen);
            advances.fill(0);
            offsets.resize(curLen);
            float currentWidth = 0;
            for (int i = 0; i < curLen; ++i, ++glyphIndex) {
                offsets[i].du = lroundf(translations[i].x());
                offsets[i].dv = -lroundf(currentWidth - translations[i].y());
                currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
            }
            SkPoint origin;
            origin.set(verticalOriginX, SkFloatToScalar(point.y() + horizontalOffset - point.x()));
            horizontalOffset += currentWidth;
            paintSkiaText(graphicsContext, font->platformData(), curLen, &glyphs[0], &advances[0], &offsets[0], &origin);
        }

        graphicsContext->setCTM(savedMatrix);
        return;
    }
#endif

    // In order to round all offsets to the correct pixel boundary, this code keeps track of the absolute position
    // of each glyph in floating point units and rounds to integer advances at the last possible moment.

    int lastHorizontalOffsetRounded = lroundf(horizontalOffset); // The rounded offset of the left side of the last glyph rendered.
    Vector<WORD, kMaxBufferLength> glyphs;
    while (glyphIndex < numGlyphs) {
        // How many chars will be in this chunk?
        int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
        glyphs.resize(curLen);
        advances.resize(curLen);

        float currentWidth = 0;
        for (int i = 0; i < curLen; ++i, ++glyphIndex) {
            glyphs[i] = glyphBuffer.glyphAt(from + glyphIndex);
            horizontalOffset += glyphBuffer.advanceAt(from + glyphIndex);
            advances[i] = lroundf(horizontalOffset) - lastHorizontalOffsetRounded;
            lastHorizontalOffsetRounded += advances[i];
            currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
            
            // Bug 26088 - very large positive or negative runs can fail to
            // render so we clamp the size here. In the specs, negative
            // letter-spacing is implementation-defined, so this should be
            // fine, and it matches Safari's implementation. The call actually
            // seems to crash if kMaxNegativeRun is set to somewhere around
            // -32830, so we give ourselves a little breathing room.
            const int maxNegativeRun = -32768;
            const int maxPositiveRun =  32768;
            if ((currentWidth + advances[i] < maxNegativeRun) || (currentWidth + advances[i] > maxPositiveRun)) 
                advances[i] = 0;
        }

        SkPoint origin = point;
        origin.fX += SkFloatToScalar(horizontalOffset - point.x() - currentWidth);
        paintSkiaText(graphicsContext, font->platformData(), curLen, &glyphs[0], &advances[0], 0, &origin);
    }
}
void SimpleFontData::platformInit() {
  if (!m_platformData.size()) {
    m_fontMetrics.reset();
    m_avgCharWidth = 0;
    m_maxCharWidth = 0;
    return;
  }

  SkPaint paint;
  SkPaint::FontMetrics metrics;

  m_platformData.setupPaint(&paint);
  paint.getFontMetrics(&metrics);
  SkTypeface* face = paint.getTypeface();
  ASSERT(face);

  int vdmxAscent = 0, vdmxDescent = 0;
  bool isVDMXValid = false;

#if OS(LINUX) || OS(ANDROID)
  // Manually digging up VDMX metrics is only applicable when bytecode hinting
  // using FreeType. With GDI, the metrics will already have taken this into
  // account (as needed). With DirectWrite or CoreText, no bytecode hinting is
  // ever done. This code should be pushed into FreeType (hinted font metrics).
  static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
  int pixelSize = m_platformData.size() + 0.5;
  if (!paint.isAutohinted() &&
      (paint.getHinting() == SkPaint::kFull_Hinting ||
       paint.getHinting() == SkPaint::kNormal_Hinting)) {
    size_t vdmxSize = face->getTableSize(vdmxTag);
    if (vdmxSize && vdmxSize < maxVDMXTableSize) {
      uint8_t* vdmxTable = (uint8_t*)fastMalloc(vdmxSize);
      if (vdmxTable &&
          face->getTableData(vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSize &&
          parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pixelSize))
        isVDMXValid = true;
      fastFree(vdmxTable);
    }
  }
#endif

  float ascent;
  float descent;

  // Beware those who step here: This code is designed to match Win32 font
  // metrics *exactly* (except the adjustment of ascent/descent on
  // Linux/Android).
  if (isVDMXValid) {
    ascent = vdmxAscent;
    descent = -vdmxDescent;
  } else {
    ascent = SkScalarRoundToInt(-metrics.fAscent);
    descent = SkScalarRoundToInt(metrics.fDescent);
#if OS(LINUX) || OS(ANDROID)
    // When subpixel positioning is enabled, if the descent is rounded down, the
    // descent part of the glyph may be truncated when displayed in a 'overflow:
    // hidden' container. To avoid that, borrow 1 unit from the ascent when
    // possible.
    // FIXME: This can be removed if sub-pixel ascent/descent is supported.
    if (platformData().fontRenderStyle().useSubpixelPositioning &&
        descent < SkScalarToFloat(metrics.fDescent) && ascent >= 1) {
      ++descent;
      --ascent;
    }
#endif
  }

  m_fontMetrics.setAscent(ascent);
  m_fontMetrics.setDescent(descent);

  float xHeight;
  if (metrics.fXHeight) {
    xHeight = metrics.fXHeight;
    m_fontMetrics.setXHeight(xHeight);
  } else {
    xHeight = ascent * 0.56;  // Best guess from Windows font metrics.
    m_fontMetrics.setXHeight(xHeight);
    m_fontMetrics.setHasXHeight(false);
  }

  float lineGap = SkScalarToFloat(metrics.fLeading);
  m_fontMetrics.setLineGap(lineGap);
  m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) +
                               lroundf(lineGap));

  SkScalar underlineThickness, underlinePosition;
  if (metrics.hasUnderlineThickness(&underlineThickness) &&
      metrics.hasUnderlinePosition(&underlinePosition)) {
    m_fontMetrics.setUnderlineThickness(SkScalarToFloat(underlineThickness));
    m_fontMetrics.setUnderlinePosition(SkScalarToFloat(-underlinePosition));
  }

  if (platformData().orientation() == Vertical &&
      !isTextOrientationFallback()) {
    static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
    static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
    size_t vheaSize = face->getTableSize(vheaTag);
    size_t vorgSize = face->getTableSize(vorgTag);
    if ((vheaSize > 0) || (vorgSize > 0))
      m_hasVerticalGlyphs = true;
  }

  // In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
  // calculated for us, but we need to calculate m_maxCharWidth and
  // m_avgCharWidth in order for text entry widgets to be sized correctly.
  // FIXME: This seems incorrect and should probably use fMaxCharWidth as
  // the code path above.
  SkScalar xRange = metrics.fXMax - metrics.fXMin;
  m_maxCharWidth =
      SkScalarRoundToInt(xRange * SkScalarRoundToInt(m_platformData.size()));

  if (metrics.fAvgCharWidth)
    m_avgCharWidth = SkScalarRoundToInt(metrics.fAvgCharWidth);
  else {
    m_avgCharWidth = xHeight;

    GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();

    if (glyphPageZero) {
      static const UChar32 xChar = 'x';
      const Glyph xGlyph = glyphPageZero->glyphForCharacter(xChar);

      if (xGlyph) {
        // In widthForGlyph(), xGlyph will be compared with
        // m_zeroWidthSpaceGlyph, which isn't initialized yet here.
        // Initialize it with zero to make sure widthForGlyph() returns
        // the right width.
        m_zeroWidthSpaceGlyph = 0;
        m_avgCharWidth = widthForGlyph(xGlyph);
      }
    }
  }

  if (int unitsPerEm = face->getUnitsPerEm())
    m_fontMetrics.setUnitsPerEm(unitsPerEm);
}
Beispiel #18
0
static int colorFloatToRGBAByte(float f)
{
    // We use lroundf and 255 instead of nextafterf(256, 0) to match CG's rounding
    return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
}
Beispiel #19
0
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
    const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs,
    const FloatPoint& point, const FloatRect& textRect) const
{
    SkScalar x = SkFloatToScalar(point.x());
    SkScalar y = SkFloatToScalar(point.y());

    const OpenTypeVerticalData* verticalData = font->verticalData();
    if (font->platformData().orientation() == Vertical && verticalData) {
        SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
        SkPoint* pos = storage.get();

        AffineTransform savedMatrix = gc->getCTM();
        gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
        gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));

        const unsigned kMaxBufferLength = 256;
        Vector<FloatPoint, kMaxBufferLength> translations;

        const FontMetrics& metrics = font->fontMetrics();
        SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAscent() - metrics.floatAscent(IdeographicBaseline));
        float horizontalOffset = point.x();

        unsigned glyphIndex = 0;
        while (glyphIndex < numGlyphs) {
            unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphIndex);

            const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
            translations.resize(chunkLength);
            verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chunkLength, reinterpret_cast<float*>(&translations[0]));

            x = verticalOriginX;
            y = SkFloatToScalar(point.y() + horizontalOffset - point.x());

            float currentWidth = 0;
            for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) {
                pos[i].set(
                    x + SkIntToScalar(lroundf(translations[i].x())),
                    y + -SkIntToScalar(-lroundf(currentWidth - translations[i].y())));
                currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
            }
            horizontalOffset += currentWidth;
            paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect);
        }

        gc->setCTM(savedMatrix);
        return;
    }

    if (!glyphBuffer.hasOffsets()) {
        SkAutoSTMalloc<64, SkScalar> storage(numGlyphs);
        SkScalar* xpos = storage.get();
        const float* adv = glyphBuffer.advances(from);
        for (unsigned i = 0; i < numGlyphs; i++) {
            xpos[i] = x;
            x += SkFloatToScalar(adv[i]);
        }
        const Glyph* glyphs = glyphBuffer.glyphs(from);
        paintGlyphsHorizontal(gc, font, glyphs, numGlyphs, xpos, SkFloatToScalar(y), textRect);
        return;
    }

    // FIXME: text rendering speed:
    // Android has code in their WebCore fork to special case when the
    // GlyphBuffer has no advances other than the defaults. In that case the
    // text drawing can proceed faster. However, it's unclear when those
    // patches may be upstreamed to WebKit so we always use the slower path
    // here.
    SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
    SkPoint* pos = storage.get();
    const FloatSize* offsets = glyphBuffer.offsets(from);
    const float* advances = glyphBuffer.advances(from);
    SkScalar advanceSoFar = SkFloatToScalar(0);
    for (unsigned i = 0; i < numGlyphs; i++) {
        pos[i].set(
            x + SkFloatToScalar(offsets[i].width()) + advanceSoFar,
            y + SkFloatToScalar(offsets[i].height()));
        advanceSoFar += SkFloatToScalar(advances[i]);
    }

    const Glyph* glyphs = glyphBuffer.glyphs(from);
    paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect);
}
Beispiel #20
0
void GPSNmea::ProcessGPRMC(uint8_t *pData)
{
    CHAR pBuff[10];
    BYTE pField[MAXFIELD];

    // Time
    if(GetField(pData, pField, 0, MAXFIELD))
    {
        // Hour
        pBuff[0] = pField[0];
        pBuff[1] = pField[1];
        pBuff[2] = '\0';
        data.hours = atoi(pBuff);

        // minute
        pBuff[0] = pField[2];
        pBuff[1] = pField[3];
        pBuff[2] = '\0';
        data.minutes = atoi(pBuff);

        // Second
        pBuff[0] = pField[4];
        pBuff[1] = pField[5];
        pBuff[2] = '\0';
        data.seconds = atoi(pBuff);
    }

    //
    // Data valid
    //
    if(GetField(pData, pField, 1, MAXFIELD)) {
        if(pField[0] == 'A') {
            if(data.altitude > 0)
                data.fixType = data.Fix3D;
            else
                data.fixType = data.Fix2D;
        }
        else
            data.fixType = data.NoFix;
    }

    //
    // latitude
    //
    if(GetField(pData, pField, 2, MAXFIELD))
    {
        data.latitude = lroundf(10000000 * atof((char *) pField + 2) / 60.0);
        pField[2] = '\0';
        data.latitude += lroundf(10000000 * atof((char *) pField));

    }
    if(GetField(pData, pField, 3, MAXFIELD))
    {
        if(pField[0] == 'S')
        {
            data.latitude = -data.latitude;
        }
    }

    //
    // Longitude
    //
    if(GetField(pData, pField, 4, MAXFIELD))
    {
        data.longitude = lroundf(10000000 * atof((CHAR *)pField+3) / 60.0);
        pField[3] = '\0';
        data.longitude += lroundf(10000000 * atof((CHAR *)pField));
    }
    if(GetField(pData, pField, 5, MAXFIELD))
    {
        if(pField[0] == 'W')
        {
            data.longitude = -data.longitude;
        }
    }

    //
    // Ground speed
    //
    if(GetField(pData, pField, 6, MAXFIELD))
    {   // convert to cm/s
        data.speed = lroundf(51.4444 * atof((CHAR *)pField));
    }
    else
    {
        data.speed = 0.0;
    }

    //
    // course over ground, degrees true converted 0.01 degree
    //
    if(GetField(pData, pField, 7, MAXFIELD))
    {
        data.heading = lroundf(100 * atof((CHAR *)pField));
    }
    else
    {
        data.heading = 0.0;
    }

    //
    // Date
    //
    if(GetField(pData, pField, 8, MAXFIELD))
    {
        // Day
        pBuff[0] = pField[0];
        pBuff[1] = pField[1];
        pBuff[2] = '\0';
        data.day = atoi(pBuff);

        // Month
        pBuff[0] = pField[2];
        pBuff[1] = pField[3];
        pBuff[2] = '\0';
        data.month = atoi(pBuff);

        // Year (Only two digits. I wonder why?)
        pBuff[0] = pField[4];
        pBuff[1] = pField[5];
        pBuff[2] = '\0';
        data.year = atoi(pBuff);
        data.year += 2000;             // make 4 digit date
    }
}
PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* patternData,
                                                                  const SVGPatternElement* patternElement,
                                                                  RenderObject* object) const
{
    PatternAttributes attributes = patternElement->collectPatternProperties();

    // If we couldn't determine the pattern content element root, stop here.
    if (!attributes.patternContentElement())
        return 0;

    FloatRect objectBoundingBox = object->objectBoundingBox();    
    FloatRect patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement); 
    AffineTransform patternTransform = attributes.patternTransform();

    AffineTransform viewBoxCTM = patternElement->viewBoxToViewTransform(patternElement->viewBox(),
                                                                        patternElement->preserveAspectRatio(),
                                                                        patternBoundaries.width(),
                                                                        patternBoundaries.height());

    FloatRect patternBoundariesIncludingOverflow = calculatePatternBoundariesIncludingOverflow(attributes,
                                                                                               objectBoundingBox,
                                                                                               viewBoxCTM,
                                                                                               patternBoundaries);

    IntSize imageSize(lroundf(patternBoundariesIncludingOverflow.width()), lroundf(patternBoundariesIncludingOverflow.height()));

    // FIXME: We should be able to clip this more, needs investigation
    clampImageBufferSizeToViewport(object->document()->view(), imageSize);

    // Don't create ImageBuffers with image size of 0
    if (imageSize.isEmpty())
        return 0;

    OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(imageSize);

    GraphicsContext* context = tileImage->context();
    ASSERT(context);

    context->save();

    // Translate to pattern start origin
    if (patternBoundariesIncludingOverflow.location() != patternBoundaries.location()) {
        context->translate(patternBoundaries.x() - patternBoundariesIncludingOverflow.x(),
                           patternBoundaries.y() - patternBoundariesIncludingOverflow.y());

        patternBoundaries.setLocation(patternBoundariesIncludingOverflow.location());
    }

    // Process viewBox or boundingBoxModeContent correction
    if (!viewBoxCTM.isIdentity())
        context->concatCTM(viewBoxCTM);
    else if (attributes.boundingBoxModeContent()) {
        context->translate(objectBoundingBox.x(), objectBoundingBox.y());
        context->scale(FloatSize(objectBoundingBox.width(), objectBoundingBox.height()));
    }

    // Render subtree into ImageBuffer
    for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
        if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
            continue;
        renderSubtreeToImage(tileImage.get(), node->renderer());
    }

    patternData->boundaries = patternBoundaries;

    // Compute pattern transformation
    patternData->transform.translate(patternBoundaries.x(), patternBoundaries.y());
    patternData->transform.multiply(patternTransform);

    context->restore();
    return tileImage.release();
}
Beispiel #22
0
void pwm_set( uint8_t number , float pwm)
{

	if ( pwm < 0 ) pwm = 0;
	
	pwm = mapf ( pwm , 0 , 1 , ( (float) PWMTOP/PWMTOP_US)*ESC_MIN , ( (float) PWMTOP/PWMTOP_US)*ESC_MAX ); 

if ( onground ) pwm = ((float)PWMTOP/PWMTOP_US) * ESC_THROTTLEOFF;
	
	if ( failsafe ) 
	{
		if ( !pwm_failsafe_time )
		{
			pwm_failsafe_time = gettime();
		}
		else
		{
			// 100mS after failsafe we turn off the signal (for safety while flashing)
			if ( gettime() - pwm_failsafe_time > 100000 )
			{
				pwm = ((float)PWMTOP/PWMTOP_US) * ESC_FAILSAFE;
			}
		}
		
	}
	else
	{
		pwm_failsafe_time = 0;
	}

	if ( pwm > ((float)PWMTOP/PWMTOP_US)*ESC_MAX ) pwm = ((float)PWMTOP/PWMTOP_US)*ESC_MAX ;

#ifdef ONESHOT_125_ENABLE
	pwm = pwm/8;
#endif
	
	pwm = lroundf(pwm);
	

	

	
    if ( pwm < 0 ) pwm = 0;
  if ( pwm > PWMTOP ) pwm = PWMTOP;
	
	

  switch( number)
	{
		case 0:
		  TIMER1->CHCC1 = (uint32_t) pwm; 	  
		break;
		
		case 1:
		  TIMER3->CHCC4 = (uint32_t) pwm; 
		break;
		
		case 2:
		  TIMER1->CHCC2 = (uint32_t) pwm; 
		break;
		
		case 3:
		  TIMER1->CHCC3 = (uint32_t) pwm; 
		break;
		
		default:
			// handle error;
			//
		break;	
				
	}
	
}
Beispiel #23
0
static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
                          int from, int numGlyphs, const FloatPoint& point)
{
    Color fillColor = graphicsContext->fillColor();

    bool drawIntoBitmap = false;
    TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode();
    if (drawingMode == TextModeFill) {
        if (!fillColor.alpha())
            return;

        drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer();
        if (!drawIntoBitmap) {
            FloatSize offset;
            float blur;
            Color color;
            ColorSpace shadowColorSpace;

            graphicsContext->getShadow(offset, blur, color, shadowColorSpace);
            drawIntoBitmap = offset.width() || offset.height() || blur;
        }
    }

    // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances.
    Vector<int, 2048> gdiAdvances;
    int totalWidth = 0;
    for (int i = 0; i < numGlyphs; i++) {
        gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i)));
        totalWidth += gdiAdvances[i];
    }

    HDC hdc = 0;
    OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
    IntRect textRect;
    if (!drawIntoBitmap)
        hdc = graphicsContext->getWindowsContext(textRect, true, false);
    if (!hdc) {
        drawIntoBitmap = true;
        // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
        // FIXME: Can get glyphs' optical bounds (even from CG) to get this right.
        const FontMetrics& fontMetrics = font->fontMetrics();
        int lineGap = fontMetrics.lineGap();
        textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
                           point.y() - fontMetrics.ascent() - lineGap,
                           totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
                           fontMetrics.lineSpacing());
        bitmap = graphicsContext->createWindowsBitmap(textRect.size());
        memset(bitmap->buffer(), 255, bitmap->bufferLength());
        hdc = bitmap->hdc();

        XFORM xform;
        xform.eM11 = 1.0f;
        xform.eM12 = 0.0f;
        xform.eM21 = 0.0f;
        xform.eM22 = 1.0f;
        xform.eDx = -textRect.x();
        xform.eDy = -textRect.y();
        SetWorldTransform(hdc, &xform);
    }

    SelectObject(hdc, font->platformData().hfont());

    // Set the correct color.
    if (drawIntoBitmap)
        SetTextColor(hdc, RGB(0, 0, 0));
    else
        SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));

    SetBkMode(hdc, TRANSPARENT);
    SetTextAlign(hdc, TA_LEFT | TA_BASELINE);

    // Uniscribe gives us offsets to help refine the positioning of combining glyphs.
    FloatSize translation = glyphBuffer.offsetAt(from);
    if (translation.width() || translation.height()) {
        XFORM xform;
        xform.eM11 = 1.0;
        xform.eM12 = 0;
        xform.eM21 = 0;
        xform.eM22 = 1.0;
        xform.eDx = translation.width();
        xform.eDy = translation.height();
        ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
    }

    if (drawingMode == TextModeFill) {
        XFORM xform;
        xform.eM11 = 1.0;
        xform.eM12 = 0;
        xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0;
        xform.eM22 = 1.0;
        xform.eDx = point.x();
        xform.eDy = point.y();
        ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
        ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
        if (font->syntheticBoldOffset()) {
            xform.eM21 = 0;
            xform.eDx = font->syntheticBoldOffset();
            xform.eDy = 0;
            ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
            ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
        }
    } else {
        XFORM xform;
        GetWorldTransform(hdc, &xform);
        AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy);
        CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity;
        if (font->platformData().syntheticOblique())
            initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0));
        initialGlyphTransform.tx = 0;
        initialGlyphTransform.ty = 0;
        CGContextRef cgContext = graphicsContext->platformContext();

        CGContextSaveGState(cgContext);

        BOOL fontSmoothingEnabled = false;
        SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0);
        CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled);

        CGContextScaleCTM(cgContext, 1.0, -1.0);
        CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height()));

        for (unsigned i = 0; i < numGlyphs; ++i) {
            RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
            CGContextSaveGState(cgContext);
            CGContextConcatCTM(cgContext, initialGlyphTransform);

            if (drawingMode & TextModeFill) {
                CGContextAddPath(cgContext, glyphPath.get());
                CGContextFillPath(cgContext);
                if (font->syntheticBoldOffset()) {
                    CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
                    CGContextAddPath(cgContext, glyphPath.get());
                    CGContextFillPath(cgContext);
                    CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
                }
            }
            if (drawingMode & TextModeStroke) {
                CGContextAddPath(cgContext, glyphPath.get());
                CGContextStrokePath(cgContext);
                if (font->syntheticBoldOffset()) {
                    CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
                    CGContextAddPath(cgContext, glyphPath.get());
                    CGContextStrokePath(cgContext);
                    CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
                }
            }

            CGContextRestoreGState(cgContext);
            CGContextTranslateCTM(cgContext, gdiAdvances[i], 0);
        }

        CGContextRestoreGState(cgContext);
    }

    if (drawIntoBitmap) {
        UInt8* buffer = bitmap->buffer();
        unsigned bufferLength = bitmap->bufferLength();
        for (unsigned i = 0; i < bufferLength; i += 4) {
            // Use green, which is always in the middle.
            UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255;
            buffer[i] = fillColor.blue();
            buffer[i + 1] = fillColor.green();
            buffer[i + 2] = fillColor.red();
            buffer[i + 3] = alpha;
        }
        graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location());
    } else
        graphicsContext->releaseWindowsContext(hdc, textRect, true, false);
}
void SimpleFontData::platformInit()
{
    if (!m_platformData.size()) {
        m_fontMetrics.reset();
        m_avgCharWidth = 0;
        m_maxCharWidth = 0;
        return;
    }

    SkPaint paint;
    SkPaint::FontMetrics metrics;

    m_platformData.setupPaint(&paint);
    paint.getFontMetrics(&metrics);
    const SkFontID fontID = m_platformData.uniqueID();

    static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
    int pixelSize = m_platformData.size() + 0.5;
    int vdmxAscent, vdmxDescent;
    bool isVDMXValid = false;

    size_t vdmxSize = SkFontHost::GetTableSize(fontID, vdmxTag);
    if (vdmxSize && vdmxSize < maxVDMXTableSize) {
        uint8_t* vdmxTable = (uint8_t*) fastMalloc(vdmxSize);
        if (vdmxTable
            && SkFontHost::GetTableData(fontID, vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSize
            && parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pixelSize))
            isVDMXValid = true;
        fastFree(vdmxTable);
    }

    float ascent;
    float descent;

    // Beware those who step here: This code is designed to match Win32 font
    // metrics *exactly*.
    if (isVDMXValid) {
        ascent = vdmxAscent;
        descent = -vdmxDescent;
    } else {
        SkScalar height = -metrics.fAscent + metrics.fDescent + metrics.fLeading;
        ascent = SkScalarRound(-metrics.fAscent);
        descent = SkScalarRound(height) - ascent;
    }

    m_fontMetrics.setAscent(ascent);
    m_fontMetrics.setDescent(descent);

    float xHeight;
    if (metrics.fXHeight)
        xHeight = metrics.fXHeight;
    else {
        // hack taken from the Windows port
        xHeight = ascent * 0.56f;
    }

    float lineGap = SkScalarToFloat(metrics.fLeading);
    m_fontMetrics.setLineGap(lineGap);
    m_fontMetrics.setXHeight(xHeight);
    m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));

    if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
        static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
        static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
        size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
        size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
        if ((vheaSize > 0) || (vorgSize > 0))
            m_hasVerticalGlyphs = true;
    }

    // In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
    // calculated for us, but we need to calculate m_maxCharWidth and
    // m_avgCharWidth in order for text entry widgets to be sized correctly.

    SkScalar xRange = metrics.fXMax - metrics.fXMin;
    m_maxCharWidth = SkScalarRound(xRange * SkScalarRound(m_platformData.size()));

    if (metrics.fAvgCharWidth)
        m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
    else {
        m_avgCharWidth = xHeight;

        GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();

        if (glyphPageZero) {
            static const UChar32 x_char = 'x';
            const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(x_char).glyph;

            if (xGlyph)
                m_avgCharWidth = widthForGlyph(xGlyph);
        }
    }
}
void RenderMathMLRoot::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
    RenderMathMLBlock::paint(info, paintOffset);
    
    if (info.context->paintingDisabled())
        return;
    
    IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location());
    
    int startX = adjustedPaintOffset.x();
    int frontWidth = lroundf(gFrontWidthEms * style()->fontSize());
    int overbarWidth = roundToInt(contentLogicalWidth()) + m_overbarLeftPointShift;
    
    int baseHeight = roundToInt(contentLogicalHeight());
    int rootPad = lroundf(gSpaceAboveEms * style()->fontSize());
    adjustedPaintOffset.setY(adjustedPaintOffset.y() - rootPad);
    
    float radicalDipLeftPointYPos = (index() ? gRootRadicalDipLeftPointYPos : gSqrtRadicalDipLeftPointYPos) * baseHeight;
    
    FloatPoint overbarLeftPoint(startX - m_overbarLeftPointShift, adjustedPaintOffset.y());
    FloatPoint bottomPoint(startX - gRadicalBottomPointXFront * frontWidth, adjustedPaintOffset.y() + baseHeight + gRadicalBottomPointLower);
    FloatPoint dipLeftPoint(startX - gRadicalDipLeftPointXFront * frontWidth, adjustedPaintOffset.y() + radicalDipLeftPointYPos);
    FloatPoint leftEnd(startX - frontWidth, dipLeftPoint.y() + gRadicalLeftEndYShiftEms * style()->fontSize());
    
    GraphicsContextStateSaver stateSaver(*info.context);
    
    info.context->setStrokeThickness(gRadicalLineThicknessEms * style()->fontSize());
    info.context->setStrokeStyle(SolidStroke);
    info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
    info.context->setLineJoin(MiterJoin);
    info.context->setMiterLimit(style()->fontSize());
    
    Path root;
    
    root.moveTo(FloatPoint(overbarLeftPoint.x() + overbarWidth, adjustedPaintOffset.y()));
    // draw top
    root.addLineTo(overbarLeftPoint);
    // draw from top left corner to bottom point of radical
    root.addLineTo(bottomPoint);
    // draw from bottom point to top of left part of radical base "dip"
    root.addLineTo(dipLeftPoint);
    // draw to end
    root.addLineTo(leftEnd);
    
    info.context->strokePath(root);
    
    GraphicsContextStateSaver maskStateSaver(*info.context);
    
    // Build a mask to draw the thick part of the root.
    Path mask;
    
    mask.moveTo(overbarLeftPoint);
    mask.addLineTo(bottomPoint);
    mask.addLineTo(dipLeftPoint);
    mask.addLineTo(FloatPoint(2 * dipLeftPoint.x() - leftEnd.x(), 2 * dipLeftPoint.y() - leftEnd.y()));
    
    info.context->clip(mask);
    
    // Draw the thick part of the root.
    info.context->setStrokeThickness(gRadicalThickLineThicknessEms * style()->fontSize());
    info.context->setLineCap(SquareCap);
    
    Path line;
    line.moveTo(bottomPoint);
    line.addLineTo(dipLeftPoint);
    
    info.context->strokePath(line);
}
Beispiel #26
0
/* Try the longest match first. */
LIB_EXPORT uint32_t CC has_right_approx_match( char *pattern, uint32_t errors, 
                                char *buf, size_t buflen, 
                                uint32_t *bestpos, uint32_t *errcnt )
{
    uint32_t plen = strlen(pattern);
    int32_t *prev = malloc(sizeof(int)*(plen+1));
    int32_t *nxt = malloc(sizeof(int)*(plen+1));
    int32_t *tmp;
    int32_t i, j;
    int32_t allowable;
    char *subpattern, chBackup;
    char *subpattern_r;
    int32_t dist;

    int32_t found = 0;
    int32_t foundpos = 0;
    int32_t founderr = 0;
    int32_t bufj;

    int bound = plen;
    if (buflen < bound) {
        bound = buflen;
    }

    subpattern = malloc(plen + 1);
    subpattern_r = malloc(plen + 1);
    strncpy(subpattern, pattern, plen);

    for (i=bound; i>=8; i--, subpattern[i] = chBackup) {

        /* See if the first i chars of the pattern match the last i
           chars of the text with (errors) errors.
           We match in reverse, so the initial penalty of skipping
           the "first part" of the pattern means skipping the end
        */
        /* making prefix of length i out of pattern
        (subpattern contains full copy of pattern)*/
        chBackup = subpattern[i];
        subpattern[i] = '\0';

        reverse_string(subpattern, i, subpattern_r);
        init_col(subpattern_r, i, nxt);

        for (j=0; j<i; j++) {
            bufj = buflen - j - 1;
            tmp = prev; prev = nxt; nxt = tmp;
            compute_dp_next_col(subpattern_r, i, 0, buf[bufj], j, prev, nxt);
        }
        dist = nxt[i];
        allowable = 1+lroundf((float)i * (float)errors / (float)plen);
        if (found) {
            if (dist <= founderr) {
                foundpos = buflen - i;
                founderr = dist;
            } else {
                goto DONE;
            }
        } else if (dist <= allowable) {
            /* Found a match */
            found = 1;
            foundpos = buflen - i;
            founderr = dist;

            /* Continue a bit to see if something's equally good or better */
        }
    }
    DONE:
    free(subpattern);
    free(subpattern_r);
    free(prev);
    free(nxt);
    if (found) {
        *bestpos = foundpos;
        *errcnt = founderr;
        return 1;
    }
    return 0;
}
PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
    const float scaledSize = lroundf(fontDescription.computedSize() * scaleFactor);
    return adoptPtr(new SimpleFontData(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false));
}
PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targetRect, FloatRect& maskDestRect) const
{    
    // Determine specified mask size
    float xValue;
    float yValue;
    float widthValue;
    float heightValue;

    if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        xValue = x().valueAsPercentage() * targetRect.width();
        yValue = y().valueAsPercentage() * targetRect.height();
        widthValue = width().valueAsPercentage() * targetRect.width();
        heightValue = height().valueAsPercentage() * targetRect.height();
    } else {
        xValue = x().value(this);
        yValue = y().value(this);
        widthValue = width().value(this);
        heightValue = height().value(this);
    } 

    IntSize imageSize(lroundf(widthValue), lroundf(heightValue));
    clampImageBufferSizeToViewport(document()->view(), imageSize);

    if (imageSize.width() < static_cast<int>(widthValue))
        widthValue = imageSize.width();

    if (imageSize.height() < static_cast<int>(heightValue))
        heightValue = imageSize.height();

    OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(imageSize, false);
    if (!maskImage)
        return 0;

    maskDestRect = FloatRect(xValue, yValue, widthValue, heightValue);
    if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
        maskDestRect.move(targetRect.x(), targetRect.y());

    GraphicsContext* maskImageContext = maskImage->context();
    ASSERT(maskImageContext);

    maskImageContext->save();
    maskImageContext->translate(-xValue, -yValue);

    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        maskImageContext->save();
        maskImageContext->scale(FloatSize(targetRect.width(), targetRect.height()));
    }

    // Render subtree into ImageBuffer
    for (Node* n = firstChild(); n; n = n->nextSibling()) {
        SVGElement* elem = 0;
        if (n->isSVGElement())
            elem = static_cast<SVGElement*>(n);
        if (!elem || !elem->isStyled())
            continue;

        SVGStyledElement* e = static_cast<SVGStyledElement*>(elem);
        RenderObject* item = e->renderer();
        if (!item)
            continue;

        renderSubtreeToImage(maskImage.get(), item);
    }

    if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
        maskImageContext->restore();

    maskImageContext->restore();
    return maskImage.release();
}
Beispiel #29
0
void SimpleFontData::platformInit(bool subpixelAscentDescent) {
  if (!m_platformData.size()) {
    m_fontMetrics.reset();
    m_avgCharWidth = 0;
    m_maxCharWidth = 0;
    return;
  }

  SkPaint::FontMetrics metrics;

  m_platformData.setupPaint(&m_paint);
  m_paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
  m_paint.getFontMetrics(&metrics);
  SkTypeface* face = m_paint.getTypeface();
  ASSERT(face);

  int vdmxAscent = 0, vdmxDescent = 0;
  bool isVDMXValid = false;

#if OS(LINUX) || OS(ANDROID)
  // Manually digging up VDMX metrics is only applicable when bytecode hinting
  // using FreeType.  With DirectWrite or CoreText, no bytecode hinting is ever
  // done.  This code should be pushed into FreeType (hinted font metrics).
  static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
  int pixelSize = m_platformData.size() + 0.5;
  if (!m_paint.isAutohinted() &&
      (m_paint.getHinting() == SkPaint::kFull_Hinting ||
       m_paint.getHinting() == SkPaint::kNormal_Hinting)) {
    size_t vdmxSize = face->getTableSize(vdmxTag);
    if (vdmxSize && vdmxSize < maxVDMXTableSize) {
      uint8_t* vdmxTable = (uint8_t*)WTF::Partitions::fastMalloc(
          vdmxSize, WTF_HEAP_PROFILER_TYPE_NAME(SimpleFontData));
      if (vdmxTable &&
          face->getTableData(vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSize &&
          parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pixelSize))
        isVDMXValid = true;
      WTF::Partitions::fastFree(vdmxTable);
    }
  }
#endif

  float ascent;
  float descent;

  // Beware those who step here: This code is designed to match Win32 font
  // metrics *exactly* except:
  // - the adjustment of ascent/descent on Linux/Android
  // - metrics.fAscent and .fDesscent are not rounded to int for tiny fonts
  if (isVDMXValid) {
    ascent = vdmxAscent;
    descent = -vdmxDescent;
  } else {
    // For tiny fonts, the rounding of fAscent and fDescent results in equal
    // baseline for different types of text baselines (crbug.com/338908).
    // Please see CanvasRenderingContext2D::getFontBaseline for the heuristic.
    if (subpixelAscentDescent &&
        (-metrics.fAscent < 3 || -metrics.fAscent + metrics.fDescent < 2)) {
      ascent = -metrics.fAscent;
      descent = metrics.fDescent;
    } else {
      ascent = SkScalarRoundToScalar(-metrics.fAscent);
      descent = SkScalarRoundToScalar(metrics.fDescent);
    }
#if OS(LINUX) || OS(ANDROID)
    // When subpixel positioning is enabled, if the descent is rounded down, the
    // descent part of the glyph may be truncated when displayed in a 'overflow:
    // hidden' container.  To avoid that, borrow 1 unit from the ascent when
    // possible.
    // FIXME: This can be removed if sub-pixel ascent/descent is supported.
    if (platformData().getFontRenderStyle().useSubpixelPositioning &&
        descent < SkScalarToFloat(metrics.fDescent) && ascent >= 1) {
      ++descent;
      --ascent;
    }
#endif
  }

#if OS(MACOSX)
  // We are preserving this ascent hack to match Safari's ascent adjustment
  // in their SimpleFontDataMac.mm, for details see crbug.com/445830.
  // We need to adjust Times, Helvetica, and Courier to closely match the
  // vertical metrics of their Microsoft counterparts that are the de facto
  // web standard. The AppKit adjustment of 20% is too big and is
  // incorrectly added to line spacing, so we use a 15% adjustment instead
  // and add it to the ascent.
  DEFINE_STATIC_LOCAL(AtomicString, timesName, ("Times"));
  DEFINE_STATIC_LOCAL(AtomicString, helveticaName, ("Helvetica"));
  DEFINE_STATIC_LOCAL(AtomicString, courierName, ("Courier"));
  String familyName = m_platformData.fontFamilyName();
  if (familyName == timesName || familyName == helveticaName ||
      familyName == courierName)
    ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
#endif

  m_fontMetrics.setAscent(ascent);
  m_fontMetrics.setDescent(descent);

  float xHeight;
  if (metrics.fXHeight) {
    xHeight = metrics.fXHeight;
#if OS(MACOSX)
    // Mac OS CTFontGetXHeight reports the bounding box height of x,
    // including parts extending below the baseline and apparently no x-height
    // value from the OS/2 table. However, the CSS ex unit
    // expects only parts above the baseline, hence measuring the glyph:
    // http://www.w3.org/TR/css3-values/#ex-unit
    const Glyph xGlyph = glyphForCharacter('x');
    if (xGlyph) {
      FloatRect glyphBounds(boundsForGlyph(xGlyph));
      // SkGlyph bounds, y down, based on rendering at (0,0).
      xHeight = -glyphBounds.y();
    }
#endif
    m_fontMetrics.setXHeight(xHeight);
  } else {
    xHeight = ascent * 0.56;  // Best guess from Windows font metrics.
    m_fontMetrics.setXHeight(xHeight);
    m_fontMetrics.setHasXHeight(false);
  }

  float lineGap = SkScalarToFloat(metrics.fLeading);
  m_fontMetrics.setLineGap(lineGap);
  m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) +
                               lroundf(lineGap));

  if (platformData().isVerticalAnyUpright() && !isTextOrientationFallback()) {
    static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
    static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
    size_t vheaSize = face->getTableSize(vheaTag);
    size_t vorgSize = face->getTableSize(vorgTag);
    if ((vheaSize > 0) || (vorgSize > 0))
      m_hasVerticalGlyphs = true;
  }

// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
// calculated for us, but we need to calculate m_maxCharWidth and
// m_avgCharWidth in order for text entry widgets to be sized correctly.
#if OS(WIN)
  m_maxCharWidth = SkScalarRoundToInt(metrics.fMaxCharWidth);

  // Older version of the DirectWrite API doesn't implement support for max
  // char width. Fall back on a multiple of the ascent. This is entirely
  // arbitrary but comes pretty close to the expected value in most cases.
  if (m_maxCharWidth < 1)
    m_maxCharWidth = ascent * 2;
#elif OS(MACOSX)
  // FIXME: The current avg/max character width calculation is not ideal,
  // it should check either the OS2 table or, better yet, query FontMetrics.
  // Sadly FontMetrics provides incorrect data on Mac at the moment.
  // https://crbug.com/420901
  m_maxCharWidth = std::max(m_avgCharWidth, m_fontMetrics.floatAscent());
#else
  // Better would be to rely on either fMaxCharWidth or fAveCharWidth.
  // skbug.com/3087
  m_maxCharWidth = SkScalarRoundToInt(metrics.fXMax - metrics.fXMin);

#endif

#if !OS(MACOSX)
  if (metrics.fAvgCharWidth) {
    m_avgCharWidth = SkScalarRoundToInt(metrics.fAvgCharWidth);
  } else {
#endif
    m_avgCharWidth = xHeight;
    const Glyph xGlyph = glyphForCharacter('x');
    if (xGlyph) {
      m_avgCharWidth = widthForGlyph(xGlyph);
    }
#if !OS(MACOSX)
  }
#endif

  if (int unitsPerEm = face->getUnitsPerEm())
    m_fontMetrics.setUnitsPerEm(unitsPerEm);
}
Beispiel #30
0
static void uavoMavlinkBridgeTask(void *parameters) {
	uint32_t lastSysTime;
	// Main task loop
	lastSysTime = PIOS_Thread_Systime();

	FlightBatterySettingsData batSettings = {};

	if (FlightBatterySettingsHandle() != NULL )
		FlightBatterySettingsGet(&batSettings);

	SystemStatsData systemStats;

	while (1) {
		PIOS_Thread_Sleep_Until(&lastSysTime, 1000 / TASK_RATE_HZ);

		if (stream_trigger(MAV_DATA_STREAM_EXTENDED_STATUS)) {
			FlightBatteryStateData batState = {};

			if (FlightBatteryStateHandle() != NULL )
				FlightBatteryStateGet(&batState);

			SystemStatsGet(&systemStats);

			int8_t battery_remaining = 0;
			if (batSettings.Capacity != 0) {
				if (batState.ConsumedEnergy < batSettings.Capacity) {
					battery_remaining = 100 - lroundf(batState.ConsumedEnergy / batSettings.Capacity * 100);
				}
			}

			uint16_t voltage = 0;
			if (batSettings.VoltagePin != FLIGHTBATTERYSETTINGS_VOLTAGEPIN_NONE)
				voltage = lroundf(batState.Voltage * 1000);

			uint16_t current = 0;
			if (batSettings.CurrentPin != FLIGHTBATTERYSETTINGS_CURRENTPIN_NONE)
				current = lroundf(batState.Current * 100);

			mavlink_msg_sys_status_pack(0, 200, mav_msg,
					// onboard_control_sensors_present Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control
					0,
					// onboard_control_sensors_enabled Bitmask showing which onboard controllers and sensors are enabled:  Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control
					0,
					// onboard_control_sensors_health Bitmask showing which onboard controllers and sensors are operational or have an error:  Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control
					0,
					// load Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000
					(uint16_t)systemStats.CPULoad * 10,
					// voltage_battery Battery voltage, in millivolts (1 = 1 millivolt)
					voltage,
					// current_battery Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current
					current,
					// battery_remaining Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery
					battery_remaining,
					// drop_rate_comm Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)
					0,
					// errors_comm Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)
					0,
					// errors_count1 Autopilot-specific errors
					0,
					// errors_count2 Autopilot-specific errors
					0,
					// errors_count3 Autopilot-specific errors
					0,
					// errors_count4 Autopilot-specific errors
					0);

			send_message();
		}

		if (stream_trigger(MAV_DATA_STREAM_RC_CHANNELS)) {
			ManualControlCommandData manualState;
			FlightStatusData flightStatus;

			ManualControlCommandGet(&manualState);
			FlightStatusGet(&flightStatus);
			SystemStatsGet(&systemStats);

			//TODO connect with RSSI object and pass in last argument
			mavlink_msg_rc_channels_raw_pack(0, 200, mav_msg,
					// time_boot_ms Timestamp (milliseconds since system boot)
					systemStats.FlightTime,
					// port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos.
					0,
					// chan1_raw RC channel 1 value, in microseconds
					manualState.Channel[0],
					// chan2_raw RC channel 2 value, in microseconds
					manualState.Channel[1],
					// chan3_raw RC channel 3 value, in microseconds
					manualState.Channel[2],
					// chan4_raw RC channel 4 value, in microseconds
					manualState.Channel[3],
					// chan5_raw RC channel 5 value, in microseconds
					manualState.Channel[4],
					// chan6_raw RC channel 6 value, in microseconds
					manualState.Channel[5],
					// chan7_raw RC channel 7 value, in microseconds
					manualState.Channel[6],
					// chan8_raw RC channel 8 value, in microseconds
					manualState.Channel[7],
					// rssi Receive signal strength indicator, 0: 0%, 255: 100%
					manualState.Rssi);

			send_message();
		}

		if (stream_trigger(MAV_DATA_STREAM_POSITION)) {
			GPSPositionData gpsPosData = {};
			HomeLocationData homeLocation = {};
			SystemStatsGet(&systemStats);

			if (GPSPositionHandle() != NULL )
				GPSPositionGet(&gpsPosData);
			if (HomeLocationHandle() != NULL )
				HomeLocationGet(&homeLocation);
			SystemStatsGet(&systemStats);

			uint8_t gps_fix_type;
			switch (gpsPosData.Status)
			{
			case GPSPOSITION_STATUS_NOGPS:
				gps_fix_type = 0;
				break;
			case GPSPOSITION_STATUS_NOFIX:
				gps_fix_type = 1;
				break;
			case GPSPOSITION_STATUS_FIX2D:
				gps_fix_type = 2;
				break;
			case GPSPOSITION_STATUS_FIX3D:
			case GPSPOSITION_STATUS_DIFF3D:
				gps_fix_type = 3;
				break;
			default:
				gps_fix_type = 0;
				break;
			}

			mavlink_msg_gps_raw_int_pack(0, 200, mav_msg,
					// time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot)
					(uint64_t)systemStats.FlightTime * 1000,
					// fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix.
					gps_fix_type,
					// lat Latitude in 1E7 degrees
					gpsPosData.Latitude,
					// lon Longitude in 1E7 degrees
					gpsPosData.Longitude,
					// alt Altitude in 1E3 meters (millimeters) above MSL
					gpsPosData.Altitude * 1000,
					// eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535
					gpsPosData.HDOP * 100,
					// epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535
					gpsPosData.VDOP * 100,
					// vel GPS ground speed (m/s * 100). If unknown, set to: 65535
					gpsPosData.Groundspeed * 100,
					// cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535
					gpsPosData.Heading * 100,
					// satellites_visible Number of satellites visible. If unknown, set to 255
					gpsPosData.Satellites);

			send_message();

			mavlink_msg_gps_global_origin_pack(0, 200, mav_msg,
					// latitude Latitude (WGS84), expressed as * 1E7
					homeLocation.Latitude,
					// longitude Longitude (WGS84), expressed as * 1E7
					homeLocation.Longitude,
					// altitude Altitude(WGS84), expressed as * 1000
					homeLocation.Altitude * 1000);

			send_message();

			//TODO add waypoint nav stuff
			//wp_target_bearing
			//wp_dist = mavlink_msg_nav_controller_output_get_wp_dist(&msg);
			//alt_error = mavlink_msg_nav_controller_output_get_alt_error(&msg);
			//aspd_error = mavlink_msg_nav_controller_output_get_aspd_error(&msg);
			//xtrack_error = mavlink_msg_nav_controller_output_get_xtrack_error(&msg);
			//mavlink_msg_nav_controller_output_pack
			//wp_number
			//mavlink_msg_mission_current_pack
		}

		if (stream_trigger(MAV_DATA_STREAM_EXTRA1)) {
			AttitudeActualData attActual;
			SystemStatsData systemStats;

			AttitudeActualGet(&attActual);
			SystemStatsGet(&systemStats);

			mavlink_msg_attitude_pack(0, 200, mav_msg,
					// time_boot_ms Timestamp (milliseconds since system boot)
					systemStats.FlightTime,
					// roll Roll angle (rad)
					attActual.Roll * DEG2RAD,
					// pitch Pitch angle (rad)
					attActual.Pitch * DEG2RAD,
					// yaw Yaw angle (rad)
					attActual.Yaw * DEG2RAD,
					// rollspeed Roll angular speed (rad/s)
					0,
					// pitchspeed Pitch angular speed (rad/s)
					0,
					// yawspeed Yaw angular speed (rad/s)
					0);

			send_message();
		}

		if (stream_trigger(MAV_DATA_STREAM_EXTRA2)) {
			ActuatorDesiredData actDesired;
			AttitudeActualData attActual;
			AirspeedActualData airspeedActual = {};
			GPSPositionData gpsPosData = {};
			BaroAltitudeData baroAltitude = {};
			FlightStatusData flightStatus;

			if (AirspeedActualHandle() != NULL )
				AirspeedActualGet(&airspeedActual);
			if (GPSPositionHandle() != NULL )
				GPSPositionGet(&gpsPosData);
			if (BaroAltitudeHandle() != NULL )
				BaroAltitudeGet(&baroAltitude);
			ActuatorDesiredGet(&actDesired);
			AttitudeActualGet(&attActual);
			FlightStatusGet(&flightStatus);

			float altitude = 0;
			if (BaroAltitudeHandle() != NULL)
				altitude = baroAltitude.Altitude;
			else if (GPSPositionHandle() != NULL)
				altitude = gpsPosData.Altitude;

			// round attActual.Yaw to nearest int and transfer from (-180 ... 180) to (0 ... 360)
			int16_t heading = lroundf(attActual.Yaw);
			if (heading < 0)
				heading += 360;

			mavlink_msg_vfr_hud_pack(0, 200, mav_msg,
					// airspeed Current airspeed in m/s
					airspeedActual.TrueAirspeed,
					// groundspeed Current ground speed in m/s
					gpsPosData.Groundspeed,
					// heading Current heading in degrees, in compass units (0..360, 0=north)
					heading,
					// throttle Current throttle setting in integer percent, 0 to 100
					actDesired.Throttle * 100,
					// alt Current altitude (MSL), in meters
					altitude,
					// climb Current climb rate in meters/second
					0);

			send_message();

			uint8_t armed_mode = 0;
			if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED)
				armed_mode |= MAV_MODE_FLAG_SAFETY_ARMED;

			uint8_t custom_mode = CUSTOM_MODE_STAB;

			switch (flightStatus.FlightMode) {
				case FLIGHTSTATUS_FLIGHTMODE_MANUAL:
				case FLIGHTSTATUS_FLIGHTMODE_MWRATE:
				case FLIGHTSTATUS_FLIGHTMODE_VIRTUALBAR:
				case FLIGHTSTATUS_FLIGHTMODE_HORIZON:
					/* Kinda a catch all */
					custom_mode = CUSTOM_MODE_SPORT;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_ACRO:
				case FLIGHTSTATUS_FLIGHTMODE_AXISLOCK:
					custom_mode = CUSTOM_MODE_ACRO;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1:
				case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2:
				case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3:
					/* May want these three to try and
					 * infer based on roll axis */
				case FLIGHTSTATUS_FLIGHTMODE_LEVELING:
					custom_mode = CUSTOM_MODE_STAB;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE:
					custom_mode = CUSTOM_MODE_DRIFT;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_ALTITUDEHOLD:
					custom_mode = CUSTOM_MODE_ALTH;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_RETURNTOHOME:
					custom_mode = CUSTOM_MODE_RTL;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_TABLETCONTROL:
				case FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD:
					custom_mode = CUSTOM_MODE_POSH;
					break;
				case FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER:
					custom_mode = CUSTOM_MODE_AUTO;
					break;
			}

			mavlink_msg_heartbeat_pack(0, 200, mav_msg,
					// type Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)
					MAV_TYPE_GENERIC,
					// autopilot Autopilot type / class. defined in MAV_AUTOPILOT ENUM
					MAV_AUTOPILOT_GENERIC,
					// base_mode System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h
					armed_mode,
					// custom_mode A bitfield for use for autopilot-specific flags.
					custom_mode,
					// system_status System status flag, see MAV_STATE ENUM
					0);

			send_message();
		}
	}
}