Package com.badlogic.gdx.graphics.g2d.BitmapFont

Examples of com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph


      bitmap = slot.getBitmap();
    }

    GlyphMetrics metrics = slot.getMetrics();

    Glyph glyph = new Glyph();
    if (bitmap != null) {
      glyph.width = bitmap.getWidth();
      glyph.height = bitmap.getRows();
    } else {
      glyph.width = 0;
View Full Code Here


    if (FreeType.loadChar(face, ' ', FreeType.FT_LOAD_DEFAULT)) {
      data.spaceWidth = FreeType.toInt(face.getGlyph().getMetrics().getHoriAdvance());
    } else {
      data.spaceWidth = face.getMaxAdvanceWidth(); // FIXME possibly very wrong :)
    }
    Glyph spaceGlyph = new Glyph();
    spaceGlyph.xadvance = (int)data.spaceWidth;
    spaceGlyph.id = (int)' ';
    data.setGlyph(' ', spaceGlyph);

    // determine x-height
    for (char xChar : BitmapFont.xChars) {
      if (!FreeType.loadChar(face, xChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.xHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }
    if (data.xHeight == 0) throw new GdxRuntimeException("No x-height character found in font");
    for (char capChar : BitmapFont.capChars) {
      if (!FreeType.loadChar(face, capChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.capHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }

    // determine cap height
    if (!bitmapped && data.capHeight == 1) throw new GdxRuntimeException("No cap character found in font");
    data.ascent = data.ascent - data.capHeight;
    data.down = -data.lineHeight;
    if (parameter.flip) {
      data.ascent = -data.ascent;
      data.down = -data.down;
    }

    boolean ownsAtlas = false;

    PixmapPacker packer = parameter.packer;

    if (packer == null) {
      // generate the glyphs
      int maxGlyphHeight = (int)Math.ceil(data.lineHeight);
      int pageWidth = MathUtils
        .nextPowerOfTwo((int)Math.sqrt(maxGlyphHeight * maxGlyphHeight * parameter.characters.length()));

      if (maxTextureSize > 0) pageWidth = Math.min(pageWidth, maxTextureSize);

      ownsAtlas = true;
      packer = new PixmapPacker(pageWidth, pageWidth, Format.RGBA8888, 2, false);
    }

    // to minimize collisions we'll use this format : pathWithoutExtension_size[_flip]_glyph
    String packPrefix = ownsAtlas ? "" : (filePath + '_' + parameter.size + (parameter.flip ? "_flip_" : '_'));

    for (int i = 0; i < parameter.characters.length(); i++) {
      char c = parameter.characters.charAt(i);
      if (!FreeType.loadChar(face, c, FreeType.FT_LOAD_DEFAULT)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't load char '" + c + "'");
        continue;
      }
      if (!FreeType.renderGlyph(face.getGlyph(), FreeType.FT_RENDER_MODE_NORMAL)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't render char '" + c + "'");
        continue;
      }
      GlyphSlot slot = face.getGlyph();
      GlyphMetrics metrics = slot.getMetrics();
      Bitmap bitmap = slot.getBitmap();
      Pixmap pixmap = bitmap.getPixmap(Format.RGBA8888);
      Glyph glyph = new Glyph();
      glyph.id = (int)c;
      glyph.width = pixmap.getWidth();
      glyph.height = pixmap.getHeight();
      glyph.xoffset = slot.getBitmapLeft();
      glyph.yoffset = parameter.flip ? -slot.getBitmapTop() + (int)baseLine : -(glyph.height - slot.getBitmapTop())
        - (int)baseLine;
      glyph.xadvance = FreeType.toInt(metrics.getHoriAdvance());

      if (bitmapped) {
        pixmap.setColor(Color.CLEAR);
        pixmap.fill();
        ByteBuffer buf = bitmap.getBuffer();
        for (int h = 0; h < glyph.height; h++) {
          int idx = h * bitmap.getPitch();
          for (int w = 0; w < (glyph.width + glyph.xoffset); w++) {
            int bit = (buf.get(idx + (w / 8)) >>> (7 - (w % 8))) & 1;
            pixmap.drawPixel(w, h, ((bit == 1) ? Color.WHITE.toIntBits() : Color.CLEAR.toIntBits()));
          }
        }

      }

      String name = packPrefix + c;
      Rectangle rect = packer.pack(name, pixmap);

      // determine which page it was packed into
      int pIndex = packer.getPageIndex(name);
      if (pIndex == -1) // we should not get here
        throw new IllegalStateException("packer was not able to insert '" + name + "' into a page");

      glyph.page = pIndex;
      glyph.srcX = (int)rect.x;
      glyph.srcY = (int)rect.y;

      data.setGlyph(c, glyph);
      pixmap.dispose();
    }

    // generate kerning
    for (int i = 0; i < parameter.characters.length(); i++) {
      for (int j = 0; j < parameter.characters.length(); j++) {
        char firstChar = parameter.characters.charAt(i);
        Glyph first = data.getGlyph(firstChar);
        if (first == null) continue;
        char secondChar = parameter.characters.charAt(j);
        Glyph second = data.getGlyph(secondChar);
        if (second == null) continue;
        int kerning = FreeType.getKerning(face, FreeType.getCharIndex(face, firstChar),
          FreeType.getCharIndex(face, secondChar), 0);
        if (kerning == 0) continue;
        first.setKerning(secondChar, FreeType.toInt(kerning));
View Full Code Here

      bitmap = slot.getBitmap();
    }

    GlyphMetrics metrics = slot.getMetrics();

    Glyph glyph = new Glyph();
    if (bitmap != null) {
      glyph.width = bitmap.getWidth();
      glyph.height = bitmap.getRows();
    } else {
      glyph.width = 0;
View Full Code Here

    if (FreeType.loadChar(face, ' ', FreeType.FT_LOAD_DEFAULT)) {
      data.spaceWidth = FreeType.toInt(face.getGlyph().getMetrics().getHoriAdvance());
    } else {
      data.spaceWidth = face.getMaxAdvanceWidth(); // FIXME possibly very wrong :)
    }
    Glyph spaceGlyph = new Glyph();
    spaceGlyph.xadvance = (int)data.spaceWidth;
    spaceGlyph.id = (int)' ';
    data.setGlyph(' ', spaceGlyph);

    // determine x-height
    for (char xChar : BitmapFont.xChars) {
      if (!FreeType.loadChar(face, xChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.xHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }
    if (data.xHeight == 0) throw new GdxRuntimeException("No x-height character found in font");
    for (char capChar : BitmapFont.capChars) {
      if (!FreeType.loadChar(face, capChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.capHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }

    // determine cap height
    if (!bitmapped && data.capHeight == 1) throw new GdxRuntimeException("No cap character found in font");
    data.ascent = data.ascent - data.capHeight;
    data.down = -data.lineHeight;
    if (flip) {
      data.ascent = -data.ascent;
      data.down = -data.down;
    }

     
    boolean ownsAtlas = false;
    if (packer==null) {
      // generate the glyphs
      int maxGlyphHeight = (int)Math.ceil(data.lineHeight);
      int pageWidth = MathUtils.nextPowerOfTwo((int)Math.sqrt(maxGlyphHeight * maxGlyphHeight * characters.length()));
       
      if (maxTextureSize > 0)
        pageWidth = Math.min(pageWidth, maxTextureSize);

      ownsAtlas = true;
      packer = new PixmapPacker(pageWidth, pageWidth, Format.RGBA8888, 2, false);
    }

    //to minimize collisions we'll use this format : pathWithoutExtension_size[_flip]_glyph
    String packPrefix = ownsAtlas ? "" : (filePath + '_' + size + (flip ? "_flip_" : '_') );
   
    for (int i = 0; i < characters.length(); i++) {
      char c = characters.charAt(i);
      if (!FreeType.loadChar(face, c, FreeType.FT_LOAD_DEFAULT)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't load char '" + c + "'");
        continue;
      }
      if (!FreeType.renderGlyph(face.getGlyph(), FreeType.FT_RENDER_MODE_NORMAL)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't render char '" + c + "'");
        continue;
      }
      GlyphSlot slot = face.getGlyph();
      GlyphMetrics metrics = slot.getMetrics();
      Bitmap bitmap = slot.getBitmap();
      Pixmap pixmap = bitmap.getPixmap(Format.RGBA8888);
      Glyph glyph = new Glyph();
      glyph.id = (int)c;
      glyph.width = pixmap.getWidth();
      glyph.height = pixmap.getHeight();
      glyph.xoffset = slot.getBitmapLeft();
      glyph.yoffset = flip ? -slot.getBitmapTop() + (int)baseLine : -(glyph.height - slot.getBitmapTop()) - (int)baseLine;
      glyph.xadvance = FreeType.toInt(metrics.getHoriAdvance());

      if(bitmapped)
      {
        pixmap.setColor(Color.CLEAR);
        pixmap.fill();
        ByteBuffer buf = bitmap.getBuffer();
        for(int h=0; h<glyph.height; h++)
        {
          int idx = h*bitmap.getPitch();
          for(int w=0; w<(glyph.width+glyph.xoffset); w++)
          {
            int bit = (buf.get(idx+(w/8)) >>> (7-(w%8))) & 1;
            pixmap.drawPixel(w, h, ((bit==1)? Color.WHITE.toIntBits() : Color.CLEAR.toIntBits()));
          }
        }
       
      }

      String name = packPrefix + c;
      Rectangle rect = packer.pack(name, pixmap);
     
      //determine which page it was packed into
      int pIndex = packer.getPageIndex(name);
      if (pIndex==-1) //we should not get here
        throw new IllegalStateException("packer was not able to insert '"+name+"' into a page");
     
      glyph.page = pIndex;
      glyph.srcX = (int)rect.x;
      glyph.srcY = (int)rect.y;
     
      data.setGlyph(c, glyph);
      pixmap.dispose();
    }

    // generate kerning
    for (int i = 0; i < characters.length(); i++) {
      for (int j = 0; j < characters.length(); j++) {
        char firstChar = characters.charAt(i);
        Glyph first = data.getGlyph(firstChar);
        if (first == null) continue;
        char secondChar = characters.charAt(j);
        Glyph second = data.getGlyph(secondChar);
        if (second == null) continue;
        int kerning = FreeType.getKerning(face, FreeType.getCharIndex(face, firstChar),
          FreeType.getCharIndex(face, secondChar), 0);
        if (kerning == 0) continue;
        first.setKerning(secondChar, FreeType.toInt(kerning));
View Full Code Here

      bitmap = slot.getBitmap();
    }

    GlyphMetrics metrics = slot.getMetrics();

    Glyph glyph = new Glyph();
    if (bitmap != null) {
      glyph.width = bitmap.getWidth();
      glyph.height = bitmap.getRows();
    } else {
      glyph.width = 0;
View Full Code Here

    if (FreeType.loadChar(face, ' ', FreeType.FT_LOAD_DEFAULT)) {
      data.spaceWidth = FreeType.toInt(face.getGlyph().getMetrics().getHoriAdvance());
    } else {
      data.spaceWidth = face.getMaxAdvanceWidth(); // FIXME possibly very wrong :)
    }
    Glyph spaceGlyph = new Glyph();
    spaceGlyph.xadvance = (int)data.spaceWidth;
    spaceGlyph.id = (int)' ';
    data.setGlyph(' ', spaceGlyph);

    // determine x-height
    for (char xChar : BitmapFont.xChars) {
      if (!FreeType.loadChar(face, xChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.xHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }
    if (data.xHeight == 0) throw new GdxRuntimeException("No x-height character found in font");
    for (char capChar : BitmapFont.capChars) {
      if (!FreeType.loadChar(face, capChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.capHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }

    // determine cap height
    if (!bitmapped && data.capHeight == 1) throw new GdxRuntimeException("No cap character found in font");
    data.ascent = data.ascent - data.capHeight;
    data.down = -data.lineHeight;
    if (parameter.flip) {
      data.ascent = -data.ascent;
      data.down = -data.down;
    }

    boolean ownsAtlas = false;

    PixmapPacker packer = parameter.packer;

    if (packer == null) {
      // generate the glyphs
      int maxGlyphHeight = (int)Math.ceil(data.lineHeight);
      int pageWidth = MathUtils
        .nextPowerOfTwo((int)Math.sqrt(maxGlyphHeight * maxGlyphHeight * parameter.characters.length()));

      if (maxTextureSize > 0) pageWidth = Math.min(pageWidth, maxTextureSize);

      ownsAtlas = true;
      packer = new PixmapPacker(pageWidth, pageWidth, Format.RGBA8888, 2, false);
    }

    // to minimize collisions we'll use this format : pathWithoutExtension_size[_flip]_glyph
    String packPrefix = ownsAtlas ? "" : (filePath + '_' + parameter.size + (parameter.flip ? "_flip_" : '_'));

    for (int i = 0; i < parameter.characters.length(); i++) {
      char c = parameter.characters.charAt(i);
      if (!FreeType.loadChar(face, c, FreeType.FT_LOAD_DEFAULT)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't load char '" + c + "'");
        continue;
      }
      if (!FreeType.renderGlyph(face.getGlyph(), FreeType.FT_RENDER_MODE_NORMAL)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't render char '" + c + "'");
        continue;
      }
      GlyphSlot slot = face.getGlyph();
      GlyphMetrics metrics = slot.getMetrics();
      Bitmap bitmap = slot.getBitmap();
      Pixmap pixmap = bitmap.getPixmap(Format.RGBA8888);
      Glyph glyph = new Glyph();
      glyph.id = (int)c;
      glyph.width = pixmap.getWidth();
      glyph.height = pixmap.getHeight();
      glyph.xoffset = slot.getBitmapLeft();
      glyph.yoffset = parameter.flip ? -slot.getBitmapTop() + (int)baseLine : -(glyph.height - slot.getBitmapTop())
        - (int)baseLine;
      glyph.xadvance = FreeType.toInt(metrics.getHoriAdvance());

      if (bitmapped) {
        pixmap.setColor(Color.CLEAR);
        pixmap.fill();
        ByteBuffer buf = bitmap.getBuffer();
        for (int h = 0; h < glyph.height; h++) {
          int idx = h * bitmap.getPitch();
          for (int w = 0; w < (glyph.width + glyph.xoffset); w++) {
            int bit = (buf.get(idx + (w / 8)) >>> (7 - (w % 8))) & 1;
            pixmap.drawPixel(w, h, ((bit == 1) ? Color.WHITE.toIntBits() : Color.CLEAR.toIntBits()));
          }
        }

      }

      String name = packPrefix + c;
      Rectangle rect = packer.pack(name, pixmap);

      // determine which page it was packed into
      int pIndex = packer.getPageIndex(name);
      if (pIndex == -1) // we should not get here
        throw new IllegalStateException("packer was not able to insert '" + name + "' into a page");

      glyph.page = pIndex;
      glyph.srcX = (int)rect.x;
      glyph.srcY = (int)rect.y;

      data.setGlyph(c, glyph);
      pixmap.dispose();
    }

    // generate kerning
    for (int i = 0; i < parameter.characters.length(); i++) {
      for (int j = 0; j < parameter.characters.length(); j++) {
        char firstChar = parameter.characters.charAt(i);
        Glyph first = data.getGlyph(firstChar);
        if (first == null) continue;
        char secondChar = parameter.characters.charAt(j);
        Glyph second = data.getGlyph(secondChar);
        if (second == null) continue;
        int kerning = FreeType.getKerning(face, FreeType.getCharIndex(face, firstChar),
          FreeType.getCharIndex(face, secondChar), 0);
        if (kerning == 0) continue;
        first.setKerning(secondChar, FreeType.toInt(kerning));
View Full Code Here

      bitmap = slot.getBitmap();
    }

    GlyphMetrics metrics = slot.getMetrics();

    Glyph glyph = new Glyph();
    if (bitmap != null) {
      glyph.width = bitmap.getWidth();
      glyph.height = bitmap.getRows();
    } else {
      glyph.width = 0;
View Full Code Here

    if (FreeType.loadChar(face, ' ', FreeType.FT_LOAD_DEFAULT)) {
      data.spaceWidth = FreeType.toInt(face.getGlyph().getMetrics().getHoriAdvance());
    } else {
      data.spaceWidth = face.getMaxAdvanceWidth(); // FIXME possibly very wrong :)
    }
    Glyph spaceGlyph = new Glyph();
    spaceGlyph.xadvance = (int)data.spaceWidth;
    spaceGlyph.id = (int)' ';
    data.setGlyph(' ', spaceGlyph);

    // determine x-height
    for (char xChar : BitmapFont.xChars) {
      if (!FreeType.loadChar(face, xChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.xHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }
    if (data.xHeight == 0) throw new GdxRuntimeException("No x-height character found in font");
    for (char capChar : BitmapFont.capChars) {
      if (!FreeType.loadChar(face, capChar, FreeType.FT_LOAD_DEFAULT)) continue;
      data.capHeight = FreeType.toInt(face.getGlyph().getMetrics().getHeight());
      break;
    }

    // determine cap height
    if (!bitmapped && data.capHeight == 1) throw new GdxRuntimeException("No cap character found in font");
    data.ascent = data.ascent - data.capHeight;
    data.down = -data.lineHeight;
    if (parameter.flip) {
      data.ascent = -data.ascent;
      data.down = -data.down;
    }

    boolean ownsAtlas = false;

    PixmapPacker packer = parameter.packer;

    if (packer == null) {
      // generate the glyphs
      int maxGlyphHeight = (int)Math.ceil(data.lineHeight);
      int pageWidth = MathUtils
        .nextPowerOfTwo((int)Math.sqrt(maxGlyphHeight * maxGlyphHeight * parameter.characters.length()));

      if (maxTextureSize > 0) pageWidth = Math.min(pageWidth, maxTextureSize);

      ownsAtlas = true;
      packer = new PixmapPacker(pageWidth, pageWidth, Format.RGBA8888, 2, false);
    }

    // to minimize collisions we'll use this format : pathWithoutExtension_size[_flip]_glyph
    String packPrefix = ownsAtlas ? "" : (filePath + '_' + parameter.size + (parameter.flip ? "_flip_" : '_'));

    for (int i = 0; i < parameter.characters.length(); i++) {
      char c = parameter.characters.charAt(i);
      if (!FreeType.loadChar(face, c, FreeType.FT_LOAD_DEFAULT)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't load char '" + c + "'");
        continue;
      }
      if (!FreeType.renderGlyph(face.getGlyph(), FreeType.FT_RENDER_MODE_NORMAL)) {
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't render char '" + c + "'");
        continue;
      }
      GlyphSlot slot = face.getGlyph();
      GlyphMetrics metrics = slot.getMetrics();
      Bitmap bitmap = slot.getBitmap();
      Pixmap pixmap = bitmap.getPixmap(Format.RGBA8888);
      Glyph glyph = new Glyph();
      glyph.id = (int)c;
      glyph.width = pixmap.getWidth();
      glyph.height = pixmap.getHeight();
      glyph.xoffset = slot.getBitmapLeft();
      glyph.yoffset = parameter.flip ? -slot.getBitmapTop() + (int)baseLine : -(glyph.height - slot.getBitmapTop())
        - (int)baseLine;
      glyph.xadvance = FreeType.toInt(metrics.getHoriAdvance());

      if (bitmapped) {
        pixmap.setColor(Color.CLEAR);
        pixmap.fill();
        ByteBuffer buf = bitmap.getBuffer();
        for (int h = 0; h < glyph.height; h++) {
          int idx = h * bitmap.getPitch();
          for (int w = 0; w < (glyph.width + glyph.xoffset); w++) {
            int bit = (buf.get(idx + (w / 8)) >>> (7 - (w % 8))) & 1;
            pixmap.drawPixel(w, h, ((bit == 1) ? Color.WHITE.toIntBits() : Color.CLEAR.toIntBits()));
          }
        }

      }

      String name = packPrefix + c;
      Rectangle rect = packer.pack(name, pixmap);

      // determine which page it was packed into
      int pIndex = packer.getPageIndex(name);
      if (pIndex == -1) // we should not get here
        throw new IllegalStateException("packer was not able to insert '" + name + "' into a page");

      glyph.page = pIndex;
      glyph.srcX = (int)rect.x;
      glyph.srcY = (int)rect.y;

      data.setGlyph(c, glyph);
      pixmap.dispose();
    }

    // generate kerning
    if (parameter.kerning) {
      for (int i = 0; i < parameter.characters.length(); i++) {
        for (int j = 0; j < parameter.characters.length(); j++) {
          char firstChar = parameter.characters.charAt(i);
          Glyph first = data.getGlyph(firstChar);
          if (first == null) continue;
          char secondChar = parameter.characters.charAt(j);
          Glyph second = data.getGlyph(secondChar);
          if (second == null) continue;
          int kerning = FreeType.getKerning(face, FreeType.getCharIndex(face, firstChar),
            FreeType.getCharIndex(face, secondChar), 0);
          if (kerning == 0) continue;
          first.setKerning(secondChar, FreeType.toInt(kerning));
View Full Code Here

      for (int i = 0, n = tmpGlyphCount.length; i < n; i++)
        tmpGlyphCount[i] = 0;

      // determine # of glyphs in each page
      while (start < end) {
        Glyph g = font.data.getGlyph(seq.charAt(start++));
        if (g == null) continue;
        tmpGlyphCount[g.page]++;
      }
      // require that many for each page
      for (int i = 0, n = tmpGlyphCount.length; i < n; i++)
View Full Code Here

  }

  private float addToCache (CharSequence str, float x, float y, int start, int end) {
    float startX = x;
    BitmapFont font = this.font;
    Glyph lastGlyph = null;
    BitmapFontData data = font.data;
    if (data.scaleX == 1 && data.scaleY == 1) {
      while (start < end) {
        lastGlyph = data.getGlyph(str.charAt(start++));
        if (lastGlyph != null) {
          addGlyph(lastGlyph, x + lastGlyph.xoffset, y + lastGlyph.yoffset, lastGlyph.width, lastGlyph.height);
          x += lastGlyph.xadvance;
          break;
        }
      }
      while (start < end) {
        char ch = str.charAt(start++);
        Glyph g = data.getGlyph(ch);
        if (g != null) {
          x += lastGlyph.getKerning(ch);
          lastGlyph = g;
          addGlyph(lastGlyph, x + g.xoffset, y + g.yoffset, g.width, g.height);
          x += g.xadvance;
        }
      }
    } else {
      float scaleX = data.scaleX, scaleY = data.scaleY;
      while (start < end) {
        lastGlyph = data.getGlyph(str.charAt(start++));
        if (lastGlyph != null) {
          addGlyph(lastGlyph, //
            x + lastGlyph.xoffset * scaleX, //
            y + lastGlyph.yoffset * scaleY, //
            lastGlyph.width * scaleX, //
            lastGlyph.height * scaleY);
          x += lastGlyph.xadvance * scaleX;
          break;
        }
      }
      while (start < end) {
        char ch = str.charAt(start++);
        Glyph g = data.getGlyph(ch);
        if (g != null) {
          x += lastGlyph.getKerning(ch) * scaleX;
          lastGlyph = g;
          addGlyph(lastGlyph, //
            x + g.xoffset * scaleX, //
View Full Code Here

TOP

Related Classes of com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.