Package com.screenrunner.ui.displays

Source Code of com.screenrunner.ui.displays.SoftwareDisplay

/*
* (c) Copyright 2009 Tim Jenkins
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package com.screenrunner.ui.displays;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.screenrunner.data.Displayable;
import com.screenrunner.data.I18n;
import com.screenrunner.data.Style;
import com.screenrunner.ui.Display;
import com.screenrunner.ScreenRunner;

public class SoftwareDisplay extends Display implements ComponentListener {

  static {
    try {
      Class.forName("org.gstreamer.Gst");
      Class.forName("com.sun.jna.Platform");
      _gstreamerSupport = true;
      I18n.print("sys/libs/gst/loadsuccess");
    } catch (ClassNotFoundException e) {
      I18n.print("sys/libs/gst/loadfail");
      I18n.print("sys/libs/gst/plugdlmsg");
    } catch (UnsatisfiedLinkError e) {
      I18n.print("sys/libs/gst/nativelibfail");
      I18n.print("sys/libs/gst/gstdlmsg");
    }
    Display.registerDisplay(new SoftwareDisplay());
  }
 
  private Panel _display;
  private Panel _preview;
  private BufferedImage _displayCache;
  private BufferedImage _displayLockCache;
  private BufferedImage _displayBgCache;
  private BufferedImage _displayFgCache;
 
  private BufferedImage _displayNextBg;
  private BufferedImage _displayNextFg;
 
  private Dimension _displaySize;
 
  private Style _curStyle;
  private String _curStyleName;
 
  private static boolean _gstreamerSupport = false;
 
  public SoftwareDisplay() {
    super();
    _display = null;
    _preview = null;
    _displayCache = null;
    _displayLockCache = null;
    _displayBgCache = null;
    _displayFgCache = null;
   
    _displayNextBg = null;
    _displayNextFg = null;
   
    _displaySize = new Dimension(800, 600);
  }
 
  @Override
  public void setBackgroundTransition(int transition, int speed) { }
 
  @Override
  public void setForegroundTransition(int transition, int speed) { }

  @Override
  public void applyChanges() {
    // set background if prepped
    if(_displayNextBg != null) {
      _displayBgCache = _displayNextBg;
      _displayNextBg = null;
    }
    // set foreground if prepped
    if(_displayNextFg != null) {
      _displayFgCache = _displayNextFg;
      _displayNextFg = null;
    }
   
    rebuildDisplayCache();
  }

  @Override
  public void initialize(int screen) {
    if(_display == null) {
      getDisplayComponent();
    }
    if(_preview == null) {
      getPreviewComponent();
    }
   
    GraphicsDevice dev = Display.getDisplayScreen();
    if(dev == null) {
      dev = Display.getPrimaryScreen();
    }
   
    ScreenRunner.log.config("Output display: " + Integer.toString(screen) + "; Resolution is: " + Integer.toString(dev.getDisplayMode().getWidth()) + "x" + Integer.toString(dev.getDisplayMode().getHeight()));
   
    _displaySize = new Dimension(dev.getDisplayMode().getWidth(), dev.getDisplayMode().getHeight());
    _displayFgCache = null;
    _displayBgCache = null;
    _displayCache = null;
    _curStyle = null;
    _curStyleName = null;
  }

  @Override
  public void prepareNextBackground(Style style, String styleName) {
    if(!needsNewBackground(style, styleName)) return;
   
    _curStyle = style;
    _curStyleName = styleName;
   
    _displayNextBg = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_RGB);
    drawBackground(_displayNextBg, style, styleName);
  }

  @Override
  public void prepareNextSlide(Displayable slide, int page, Style style) {
    _displayNextFg = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_ARGB);
    if(slide == null || page < 0) return;
    drawForeground(_displayNextFg, slide, page, style);
  }

  @Override
  public void dispose() { }
 
  @SuppressWarnings("serial")
  private Panel createSpecialCanvas(boolean isDisplay) {
    Panel c;
    if(isDisplay) {
      c = new Panel() {
       
        @Override
        public void paint(Graphics g) {
          drawDisplayCache(this, true);
        }
      };
    } else {
      c = new Panel() {

        @Override
        public void paint(Graphics g) {
          drawDisplayCache(this, false);
        }
      };
    }
    c.setSize(100, 100);
    c.addComponentListener(this);
    return c;
  }

  @Override
  public Component getDisplayComponent() {
    if(_display == null) {
      _display = createSpecialCanvas(true);
    }
    return _display;
  }

  @Override
  public Component getPreviewComponent() {
    if(_preview == null) {
      _preview = createSpecialCanvas(false);
    }
    return _preview;
  }
 
  private void drawBackground(BufferedImage cache, Style style, String bgStyle) {
    if(cache == null || style == null || bgStyle == null) return;
   
    int w = cache.getWidth();
    int h = cache.getHeight();
   
    Graphics2D g = (Graphics2D)cache.getGraphics();
   
    g.setColor(style.getBackgroundColor(bgStyle));
    g.fillRect(0, 0, w, h);
   
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    String bgurl = style.getBackgroundUrl(bgStyle);
    if(bgurl != null && bgurl.length() > 0) {
      BufferedImage img;
      File imgfile = new File(style.getBackgroundUrl(bgStyle));
      if(imgfile == null || !imgfile.exists()) return;
      try {
        img = ImageIO.read(imgfile);
      } catch (IOException e) {
        System.err.println("Error reading background image!");
        e.printStackTrace();
        return;
      }
      if(img == null) return;
      int iw = img.getWidth();
      int ih = img.getHeight();
      int bgmode = style.getBackgroundMode(bgStyle);
     
      if(bgmode == Style.BGMODE_STRETCH) {
        while(!g.drawImage(img, 0, 0, w, h, 0, 0, iw, ih, _display)) continue;
      }
      else if(bgmode == Style.BGMODE_CENTER) {
        int x = (w - iw) / 2;
        int y = (h - ih) / 2;
        while(!g.drawImage(img, x, y, _display)) continue;
      }
      else if(bgmode == Style.BGMODE_ZOOM) {
        float aspectScreen = (float)h / (float)w;
        float aspectImage = (float)ih / (float)iw;
        int nw = w;
        int nh = h;
        if(aspectScreen <= aspectImage) {
          nw = (int)Math.floor(((float)h / (float)ih) * iw);
        } else {
          nh = (int)Math.floor(((float)w / (float)iw) * ih);
        }
        int x = (w - nw) / 2;
        int y = (h - nh) / 2;
       
        while(!g.drawImage(img, x, y, nw, nh, _display)) continue;
      }
      else {
        System.err.println("Invalid background mode: " + Integer.toString(bgmode));
      }
    }
  }
 
  private void drawForeground(BufferedImage cache, Displayable slide, int page, Style style) {
    if(cache == null || slide == null || style == null) return;
   
    Graphics2D g = cache.createGraphics();
    Composite comp = g.getComposite();
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
    g.fillRect(0, 0, cache.getWidth(null), cache.getHeight(null));
    g.setComposite(comp);
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
   
    slide.drawPage(page, g, _displaySize, style, 1.0f);
  }
 
  private void rebuildDisplayCache() {
    if(_displaySize.width <= 0 || _displaySize.height <= 0) return;
   
    if(_displayCache == null)
      _displayCache = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_RGB);
    if(_displayBgCache == null)
      _displayBgCache = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_RGB);
    if(_displayFgCache == null)
      _displayFgCache = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_ARGB);
   
    Graphics2D g = _displayCache.createGraphics();
    if(getDisplayMode() == DISPMODE_OFF || getDisplayMode() == DISPMODE_NORMAL) {
      while(!g.drawImage(_displayBgCache, 0, 0, _displaySize.width, _displaySize.height, null)) continue;
      g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
      while(!g.drawImage(_displayFgCache, 0, 0, _displaySize.width, _displaySize.height, null)) continue;
    }
    else if(getDisplayMode() == DISPMODE_BACKGROUND) {
      while(!g.drawImage(_displayBgCache, 0, 0, _displaySize.width, _displaySize.height, null)) continue;
    }
    else if(getDisplayMode() == DISPMODE_BLACK) {
      g.setColor(Color.black);
      g.fillRect(0, 0, _displaySize.width, _displaySize.height);
    }
    else if(getDisplayMode() == DISPMODE_LOGO) {
      while(!g.drawImage(_displayBgCache, 0, 0, _displaySize.width, _displaySize.height, null)) continue;
      g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
     
      if(ScreenRunner.logo != null) {
        int scw = (int)(_displaySize.width * 0.8);
        int sch = (int)(_displaySize.height * 0.8);
        int lgw = ScreenRunner.logo.getWidth();
        int lgh = ScreenRunner.logo.getHeight();
       
        double scasp = (double)scw / (double)sch;
        double asp = (double)lgw / (double)lgh;
       
        if(asp >= scasp) {
          sch = (int)(((double)scw / (double)lgw) * lgh);
        } else {
          scw = (int)(((double)sch / (double)lgh) * lgw);
        }
       
        int scx = (_displaySize.width - scw) / 2;
        int scy = (_displaySize.height - sch) / 2;
       
        while(!g.drawImage(ScreenRunner.logo, scx, scy, scw, sch, null)) continue;
      }
    }
   
    if(_display != null) drawDisplayCache(_display, true);
    if(_preview != null) drawDisplayCache(_preview, false);
  }
 
  public void drawDisplayCache(Component target, boolean isDisplay) {
    if(target == null) return;
    if(!target.isVisible()) return;
   
    int tw = target.getWidth();
    int th = target.getHeight();
    if(tw == 0 || th == 0) return;
   
    BufferedImage cache = ((isDisplay && isDisplayLocked()) ? _displayLockCache : _displayCache);
   
    Graphics2D g = (Graphics2D)target.getGraphics();
    if(g == null) return;
    if(cache == null) {
      g.setColor(Color.black);
      g.fillRect(0, 0, tw, th);
    } else {
      if(cache.getWidth() != tw || cache.getHeight() != th) {
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
      }
      while(!g.drawImage(cache, 0, 0, tw, th, null)) continue;
    }
   
    if(!isDisplay && isDisplayLocked()) {
      g.drawImage(ScreenRunner.lockImg, tw - 48, th - 48, 48, 48, null);
    }
   
    g.dispose();
  }
 
  @Override
  public void componentHidden(ComponentEvent e) { }

  @Override
  public void componentMoved(ComponentEvent e) { }

  @Override
  public void componentResized(ComponentEvent e) {
    Component c = e.getComponent();
    if(c == _display || c == _preview) {
      drawDisplayCache(c, (c == _display));
    }
  }

  @Override
  public void componentShown(ComponentEvent e) {
    Component c = e.getComponent();
    if(c == _display || c == _preview) {
      drawDisplayCache(c, (c == _display));
    }
  }

  @Override
  public void updateDisplays() {
    _displayCache = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_RGB);

    rebuildDisplayCache();
    if(_display != null && _display.isVisible()) drawDisplayCache(_display, true);
    if(_preview != null && _preview.isVisible()) drawDisplayCache(_preview, false);
  }

  @Override
  protected void onDisplayLockChanged(boolean locked) {
    if(locked) {
      _displayLockCache = new BufferedImage(_displaySize.width, _displaySize.height, BufferedImage.TYPE_INT_RGB);
      while(!_displayLockCache.getGraphics().drawImage(_displayCache, 0, 0, _displaySize.width, _displaySize.height, null)) continue;
    }
    if(_display != null) drawDisplayCache(_display, true);
    if(_preview != null) drawDisplayCache(_preview, false);
  }

  @Override
  protected void onDisplayModeChanged(int mode) {
    updateDisplays();
  }

  private boolean needsNewBackground(Style style, String styleName) {
    return ((style != _curStyle) || (styleName != _curStyleName));
  }

  @Override
  public String getFriendlyName() { return "Software"; }

  @Override
  public boolean isAccelerated() { return false; }

  @Override
  public boolean supportsMedia() { return _gstreamerSupport; }
 
}
TOP

Related Classes of com.screenrunner.ui.displays.SoftwareDisplay

TOP
Copyright © 2018 www.massapi.com. 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.